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