是否可以在Ansible中设置数组的事实?

时间:2014-05-07 02:16:19

标签: ansible

是否可以使用set_fact在ansible中设置包含数组的事实?它的正确语法是什么?

6 个答案:

答案 0 :(得分:32)

是的,这是可能的。如另一个答案所述,您可以使用双引号设置数组,如下所示:

- name: set foo fact to an array
  set_fact: foo="[ 'one', 'two', 'three' ]"

但是,我想我会创建另一个答案,表明它也可以添加到现有数组中,如下所示:

- name: add items to foo array 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   

答案 1 :(得分:20)

确实如此。您需要引用整个数组:

- 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"
}

答案 2 :(得分:10)

添加已经给出的答案,我想向您展示一种不同的方式 使用常规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

答案 3 :(得分:4)

我有类似的要求,根据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"
            }
        }
    ]
}

答案 4 :(得分:0)

我不知道功能是否发生了变化---可能在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

答案 5 :(得分:0)

喜欢这个

- hosts: all
  tasks:
  - set_fact:
      redis_list: |
        {%- set list = [] -%}
        {%- for index in range(1, 5 ) -%}
          {{ list.append(index)  }}
        {%- endfor -%}
        {{ list }}