Is it possible to set a fact of an array in Ansible?

匿名 (未验证) 提交于 2019-12-03 02:44:02

问题:

Is it possible to set a fact containing an array in ansible using set_fact? What's the correct syntax for it?

回答1:

Indeed it is. You need to quote the entire array though:

- name: set fact   set_fact: foo="[ 'one', 'two', 'three']"  - name: debug   debug: msg={{ item }}   with_items: foo 

The above tasks should generate the following output:

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:

Yes, this is possible. As mentioned in another answer, you can set an array using double quotes, like so:

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

However, I thought I'd create another answer to indicate that it's also possible to add to an existing array, like so:

- name: add items to foo array fact   set_fact: foo="{{foo}} + [ 'four' ]" 

Combining these and adding debugging as a playbook (which I'm calling facts.yml) like so:

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

Produces (via ansible-playbook facts.yml) the following:

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    


回答3:

Adding to the already given answers I would like to show you a different way to define a list with set_fact using the regular YAML syntax instead of the custom format which Ansible core folks like to use in their docs. This custom format, like in this case, has shown lead to confusion.

Consider this example:

- name: 'Set the foo variable to a static list using the YAML syntax'   set_fact:     foo:       - 'one'       - 'two'       - 'three' 

Straight forward, right? Just as you would do in any normal YAML document. So why not use it in Ansible YAML tasks file too?

About the combination of lists mentioned by @lindes-hw. There is more than one way to do this. The following examples use Jinja2 syntax to define the list:

- 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" ]) }}' 

The second example uses the union filter. Refer to the set theory filters in the Ansible docs.



回答4:

I had a similar requirement to create list of server objects based on list of IP addresses.

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

Gives following output

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!