Ansible Pattern: Templated Dictionary Keys
Except for cases like set_fact
where this functionality has been
specifically implemented, Ansible does not template dictionary keys.
This means you cannot do things like this:
- name: Create a frobnitz
frobnitz:
frobnicators:
"{{ foo }}": bar
Templating Dictionaries
As a workaround you can template the entire dictionary. In the simplest cases it isn’t unbearably ugly to do this inline:
- name: Create a frobnitz
frobnitz:
frobnicators: "{{ { foo: 'bar' } }}"
However, for even moderately complex structures it quickly becomes a pain to keep track of the Jinja data structure syntax when you’re more used to reading and writing YAML:
- name: Create a complicated frobnitz
frobnitz:
frobnicators: "{{ {
foo: 'bar',
'foo2': {
'bar': 'baz',
},
'foo3': bar,
} }}"
This is where I might use task vars to break the structure up into more readable declarations:
- name: Create a complicated frobnitz
frobnitz:
frobnicators: "{{ frobnicators | combine(t_frobnicators) }}"
vars:
frobnicators:
foo2:
bar: baz
foo3: "{{ bar }}"
t_frobnicators: "{{ { foo: 'bar' } }}"
Templating Lists
You can also employ more roundabout options, like creating a list with templated values that is easily transformable into a dictionary:
- name: Create a complicated frobnitz
frobnitz:
frobnicators: "{{ frobnicators | items2dict }}"
vars:
frobnicators:
- key: "{{ foo }}"
value: bar
- key: foo2
value:
bar: baz
- key: foo3
value: "{{ bar }}"
Templating Strings
Another approach I’ve seen is to use Ansible’s key=value
syntax
(which is automatically converted to a dictionary in many, but not
all, cases) instead of YAML:
- name: Create an intermediate frobnitz
frobnitz:
frobnicators: "{{ foo }}=bar foo3={{ bar }}"
This has limitations that aren’t present with proper data structures, but it can still be useful.