If I start with a yaml object provided by test-kitchen like this;
vars:
wp_sites:
- site_subdomain: wordpress1
theme: twentyseventeen
site_tld: testbox
- { site_subdomain: wordpress2, theme: just-pink, site_tld: testbox }
- site_subdomain: wordpress3
plugins:
- disable-comments
site_tld: testbox
I might need to process the subkeys of that in some way. But unfortunately the
set_fact
module is pretty simple, and expects to receive a single variable as
output. You can’t for example do this;
- set_fact:
wp_sites[{ { item }}]:
plugins: "{{ wp_site.plugins|default([]) }}"
with_items: "{{ wp_sites }}"
as the subkey cannot be complex. So you have to take advantage of jinjas methods for aggregating
- set_fact:
wp_sites[{ { item }}]:
plugins: "{{ wp_site.plugins|default([]) }}"
theme: "{{ wp_site.theme|default('') }}"
site: "{{ wp_site.site_subdomain }}.{{ wp_site.site_domain | default(ansible_hostname) }}.{{ wp_site.site_tld }}"
site_subdomain: "{{ wp_site.site_tld|default('') }}"
site_domain: "{{ wp_site.site_tld|default('') }}"
site_tld: "{{ wp_site.site_tld|default('') }}"
with_items: "{{ wp_sites }}"
The new combine filter makes it possible to build up hashes using set_fact. Note the use of default({})
to address the possibility that x is not defined.
# x → {'a': 111, 'b': 222, 'c': 333}
- set_fact:
x: "{{ x|default({})|combine({item.0: item.1}) }}"
with_together:
- ['a', 'b', 'c']
- [111, 222, 333]
Thanks to the union filter, you can do the same with lists. Combining these techniques makes it possible to build up complex data structures dynamically.
# y → [{'a':123}, {'b':456}, {'c':789}]
- set_fact:
y: "{{ y|default([])|union([{item.0: item.1}]) }}"
with_together:
- ['a', 'b', 'c']
- [111, 222, 333]