Appending to lists or adding keys to dictionaries in Ansible
Solution 1:
Since Ansible v2.x you can do these:
# use case I: appending to LIST variable:
- name: my appender
set_fact:
my_list_var: '{{my_list_myvar + new_items_list}}'
# use case II: appending to LIST variable one by one:
- name: my appender
set_fact:
my_list_var: '{{my_list_var + [item]}}'
with_items: '{{my_new_items|list}}'
# use case III: appending more keys DICT variable in a "batch":
- name: my appender
set_fact:
my_dict_var: '{{my_dict_var|combine(my_new_keys_in_a_dict)}}'
# use case IV: appending keys DICT variable one by one from tuples
- name: setup list of tuples (for 2.4.x and up
set_fact:
lot: >
[('key1', 'value1',), ('key2', 'value2',), ..., ('keyN', 'valueN',)],
- name: my appender
set_fact:
my_dict_var: '{{my_dict_var|combine({item[0]: item[1]})}}'
with_items: '{{lot}}'
# use case V: appending keys DICT variable one by one from list of dicts (thanks to @ssc)
- name: add new key / value pairs to dict
set_fact:
my_dict_var: "{{ my_dict_var | combine({item.key: item.value}) }}"
with_items:
- { key: 'key01', value: 'value 01' }
- { key: 'key02', value: 'value 03' }
- { key: 'key03', value: 'value 04' }
all the above is documented in: http://docs.ansible.com/ansible/playbooks_filters.html
Solution 2:
You can merge two lists in a variable with +
.
Say you have a group_vars
file with this content:
---
# group_vars/all
pgsql_extensions:
- ext1
- ext2
- ext3
And it's used in a template pgsql.conf.j2
like:
# {{ ansible_managed }}
pgsql_extensions={% for item in pgsql_extensions %}{{ item }}, {% endfor %}
You can then append extensions to the testing database servers like this:
---
# group_vars/testing_db
append_exts:
- ext4
- ext5
pgsql_extensions: "{{ pgsql_extensions + append_exts }}"
When the role is run in any of the testing servers, the aditional extensions will be added.
I'm not sure this works for dictionaries as well, and also be careful with spaces and leaving a dangling comma at the end of the line.
Solution 3:
you need to split the loop into 2
--- - hosts: localhost tasks: - include_vars: stacks - set_facts: roles={{stacks.Roles | split(' ')}} - include: addhost.yml with_items: "{{roles}}"
and addhost.yml
- set_facts: groupname={{item}} - set_facts: ips={{stacks[item]|split(' ')}} - local_action: add_host hostname={{item}} groupname={{groupname}} with_items: {{ips}}