首页 文章

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

提问于
浏览
31

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

5 回答

  • 9

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

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

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

    - 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

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

    考虑这个例子:

    - 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 .

  • 31

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

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

相关问题