我目前正在使用Ansible 1.7.2.我有以下测试剧本:
---
- hosts: localhost
tasks:
- name: set fact 1
set_fact: foo="[ 'zero' ]"
- name: set fact 2
set_fact: foo="{{ foo }} + [ 'one' ]"
- name: set fact 3
set_fact: foo="{{ foo }} + [ 'two', 'three' ]"
- name: set fact 4
set_fact: foo="{{ foo }} + [ '{{ item }}' ]"
with_items:
- four
- five
- six
- debug: var=foo
Run Code Online (Sandbox Code Playgroud)
第一个任务设置一个事实,即列表中包含一个项目.后续任务将附加更多值附加到该列表.前三个任务按预期工作,但最后一个没有.这是我运行时的输出:
PLAY [localhost] **************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [set fact 1] ************************************************************
ok: [localhost]
TASK: [set fact 2] ************************************************************
ok: [localhost]
TASK: [set fact 3] ************************************************************
ok: [localhost]
TASK: [set fact 4] ************************************************************
ok: [localhost] => (item=four)
ok: [localhost] => (item=five)
ok: [localhost] => (item=six)
TASK: [debug var=foo] *********************************************************
ok: [localhost] => {
"foo": [
"zero",
"one",
"two",
"three",
"six"
]
}
PLAY RECAP ********************************************************************
localhost : ok=6 changed=0 unreachable=0 failed=0
Run Code Online (Sandbox Code Playgroud)
鉴于任务4中的with_items以及输出显示任务在该列表中的项目上正确迭代的事实,我希望结果包含从0到6的所有数字.但是最后一个任务似乎只是用列表中的最后一项来评估set_fact.这可能是Ansible的一个错误吗?
编辑:我也刚刚在ansible 1.8上测试过,输出结果相同.
小智 79
有一种解决方法可能有所帮助.您可以为每个set_fact迭代"注册"结果,然后将结果映射到列表:
---
- hosts: localhost
tasks:
- name: set fact
set_fact: foo_item="{{ item }}"
with_items:
- four
- five
- six
register: foo_result
- name: make a list
set_fact: foo="{{ foo_result.results | map(attribute='ansible_facts.foo_item') | list }}"
- debug: var=foo
Run Code Online (Sandbox Code Playgroud)
输出:
< TASK: debug var=foo >
---------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
ok: [localhost] => {
"var": {
"foo": [
"four",
"five",
"six"
]
}
}
Run Code Online (Sandbox Code Playgroud)
小智 12
正如其他人的评论中所提到的,这里给出的最佳解决方案在Ansible 2.2中并不适用于我,特别是在使用时with_items.
似乎OP的预期方法现在可以正常工作,引用略有变化item.
- set_fact: something="{{ something + [ item ] }}"
with_items:
- one
- two
- three
Run Code Online (Sandbox Code Playgroud)
还有一个较长的例子,我处理了列表的初始情况未定义并添加了一个可选项,when因为这也让我感到悲伤:
- set_fact: something="{{ something|default([]) + [ item ] }}"
with_items:
- one
- two
- three
when: item.name in allowed_things.item_list
Run Code Online (Sandbox Code Playgroud)
Gra*_*han 10
我正在四处寻找这个问题的答案。我发现这很有帮助。该模式在 with_items 的文档中并不明显。
https://github.com/ansible/ansible/issues/39389
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: set_fact
set_fact:
foo: "{{ foo }} + [ '{{ item }}' ]"
with_items:
- "one"
- "two"
- "three"
vars:
foo: []
- name: Print the var
debug:
var: foo
Run Code Online (Sandbox Code Playgroud)
Jinja 2.6没有map功能.所以另一种方法是:
set_fact: foo="{% for i in bar_result.results %}{{ i.ansible_facts.foo_item }}{%endfor%}"
Run Code Online (Sandbox Code Playgroud)
小智 6
以下对我有用:
- name: set fact
set_fact:
foo_item: "{{foo_item | default([]) + [item]}}"
loop:
- four
- five
- six
Run Code Online (Sandbox Code Playgroud)