【发布时间】:2014-05-07 02:16:18
【问题描述】:
是否可以使用set_fact 在 Ansible 中设置包含列表的事实?它的正确语法是什么?
【问题讨论】:
标签: ansible
是否可以使用set_fact 在 Ansible 中设置包含列表的事实?它的正确语法是什么?
【问题讨论】:
标签: ansible
是的,这是可能的。如另一个答案中所述,您可以使用双引号设置数组,如下所示:
- name: set foo fact to a list
set_fact:
foo: "[ 'one', 'two', 'three' ]"
但是,我想我会创建另一个答案来表明它也可以添加到现有数组中,如下所示:
- name: add items to foo list fact
set_fact:
foo: "{{foo}} + [ 'four' ]"
结合这些并将调试添加为剧本(我称之为facts.yml),如下所示:
---
- name: test playbook
gather_facts: false
hosts: localhost
tasks:
- name: set foo fact to an array
set_fact:
foo: "[ 'one', 'two', 'three' ]"
- debug:
var: foo
- name: add items to foo array fact
set_fact:
foo: "{{foo}} + [ 'four' ]"
- debug:
var: foo
产生(通过ansible-playbook facts.yml)以下内容:
PLAY [test playbook] ********************************************************
TASK: [set foo fact to an array] ********************************************
ok: [localhost]
TASK: [debug var=foo] *******************************************************
ok: [localhost] => {
"foo": [
"one",
"two",
"three"
]
}
TASK: [add items to foo array fact] *****************************************
ok: [localhost]
TASK: [debug var=foo] *******************************************************
ok: [localhost] => {
"foo": [
"one",
"two",
"three",
"four"
]
}
PLAY RECAP ******************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0
【讨论】:
foo=[] 开头然后附加一个模板字符串而不是'four',这将如何工作?例如,我将在下面提供一个“答案”来解释这个问题。
确实如此。不过,您需要引用整个列表:
- name: set fact
set_fact: foo="[ 'one', 'two', 'three' ]"
- name: debug
debug: msg={{ item }}
with_items: foo
上述任务应生成以下输出:
TASK: [set fact] **************************************************************
ok: [localhost]
TASK: [debug] *****************************************************************
ok: [localhost] => (item=one) => {
"item": "one",
"msg": "one"
}
ok: [localhost] => (item=two) => {
"item": "two",
"msg": "two"
}
ok: [localhost] => (item=three) => {
"item": "three",
"msg": "three"
}
【讨论】:
除了已经给出的答案之外,我想向您展示一种不同的方式
使用常规 YAML 语法而不是使用 set_fact 定义列表
Ansible 核心人员喜欢在他们的文档中使用的自定义格式。这
像这种情况下的自定义格式已显示会导致混淆。
考虑这个例子:
- name: 'Set the foo variable to a static list using the YAML syntax'
set_fact:
foo:
- 'one'
- 'two'
- 'three'
直截了当,对吧?就像您在任何普通的 YAML 文档中所做的一样。所以 为什么不在 Ansible YAML 任务文件中使用它呢?
关于@lindes-hw 提到的列表组合。不止一个 方法来做到这一点。以下示例使用 Jinja2 语法定义列表:
- name: 'Set the foo variable to a combined static list using the Jinja2 syntax'
set_fact:
foo: '{{ [ "one" ] + [ "two", "three" ] }}'
- name: 'Set the foo variable to a combined static list using the Jinja2 syntax and Jinja2 filters'
set_fact:
foo: '{{ [ "one" ] | union([ "two", "three" ]) }}'
第二个示例使用union 过滤器。参考set theory filters in the Ansible docs。
【讨论】:
我有一个类似的要求,即根据 IP 地址列表创建服务器对象列表。
vars:
server_ips: one,two,three
tasks:
- name: build items list
set_fact:
foo: "{{foo|default([]) + [{'ip': {'addr': item, 'type': 'V4'}}] }}"
with_items: "{{server_ips.split(',')}}"
- debug:
msg: "{{ foo }}"
给出以下输出
TASK [setup] *******************************************************************
ok: [localhost]
TASK [build items list] ********************************************************
ok: [localhost] => (item=one)
ok: [localhost] => (item=two)
ok: [localhost] => (item=three)
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": [
{
"ip": {
"addr": "one",
"type": "V4"
}
},
{
"ip": {
"addr": "two",
"type": "V4"
}
},
{
"ip": {
"addr": "three",
"type": "V4"
}
}
]
}
【讨论】:
我不知道功能是否发生了变化——它可能在 2.5 中发生了——但在我看来就像这段代码
with_items: foo
在示例中不再起作用,您必须使用
with_items: "{{ foo }}"
我正在使用 Ansible 2.5.2。我得到了这个(不正确的)输出:
ok:[localhost] => (item=None) => {
"msg":"foo"
}
我在此处的文档中找到了更新的语法:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#with-items
【讨论】:
喜欢这个
- hosts: all
tasks:
- set_fact:
redis_list: |
{%- set list = [] -%}
{%- for index in range(1, 5 ) -%}
{{ list.append(index) }}
{%- endfor -%}
{{ list }}
【讨论】: