One of the most often-requested features in Ansible was a way to merge
hashes. This has been discussed many times on
the mailing lists
and on IRC and on
stackoverflow,
and implemented in
at least
five
different
pull
requests
submitted to Ansible, and who knows in how many private filter plugins.
Ansible 2 (currently in β2) finally includes a
way to do this:
the ‘combine’ filter. The
filter documentation
has examples of its use, but here's the basic idea:
{'a':1, 'b':2}|combine({'b':3})
→ {'a':1, 'b':3}
{'a':{'x':1}}|combine({'a':{'y':2}}, recursive=True)
→ {'a':{'x':1, 'y':2}}
The
“hash_behaviour=merge”
configuration setting offers similar (recursive-only) functionality, but
it's a global setting, and not convenient to use.
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]