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

xia*_*amx 34 ansible

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

lin*_*-hw 33

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

- name: set foo fact to an array
  set_fact: foo="[ 'one', 'two', 'three' ]"
Run Code Online (Sandbox Code Playgroud)

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

- name: add items to foo array fact
  set_fact: foo="{{foo}} + [ 'four' ]"
Run Code Online (Sandbox Code Playgroud)

结合这些并添加调试作为一个剧本(我正在调用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
Run Code Online (Sandbox Code Playgroud)

生成(通过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   
Run Code Online (Sandbox Code Playgroud)

  • 很棒的答案......但是有一个问题 - 怎么!!?!?我们应该知道这个吗?我在文档中看不到这样的内容 (4认同)

Bru*_*e P 20

的确是.您需要引用整个数组:

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

- name: debug
  debug: msg={{ item }}
  with_items: foo
Run Code Online (Sandbox Code Playgroud)

上述任务应生成以下输出:

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"
}
Run Code Online (Sandbox Code Playgroud)


ypi*_*pid 11

添加到已经给出的答案,我想向您展示set_fact使用常规YAML语法而不是Ansible核心人员喜欢在其文档中使用的自定义格式来定义列表的不同方法.这种自定义格式,就像在这种情况下,已经显示出导致混淆.

考虑这个例子:

- name: 'Set the foo variable to a static list using the YAML syntax'
  set_fact:
    foo:
      - 'one'
      - 'two'
      - 'three'
Run Code Online (Sandbox Code Playgroud)

直接向前吧?就像在任何普通的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" ]) }}'
Run Code Online (Sandbox Code Playgroud)

第二个示例使用union过滤器.请参阅Ansible文档中集合理论过滤器.

  • +1保持简单。Ansible 的主要卖点之一是您可以使用易于阅读(和编写)的 YAML 语法,因此我总是困惑为什么许多 Ansible 示例代码毫无理由地令人费解。 (2认同)

小智 5

我有类似的要求,可以根据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 }}"
Run Code Online (Sandbox Code Playgroud)

提供以下输出

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"
            }
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)