What I am trying to achieve is the following. Suppose we have a playbook similar to the following one:
---
- hosts: local
tasks:
- ini_file:
path: test.ini
create: yes
section: "{{???}}"
option: "{{???}}"
value: "{{???}}"
loop: "{{inidict ...???}}"
vars:
inidict:
section1:
option1: value1
option2: value2
section2:
option1: value1
option2: value2
The above playbook is invalid because of the lines with ???
in them.
Now my goal here is to map this dict to sections/options/values inside the INI file and get the following INI contents:
[section1]
option1 = value1
option2 = value2
[section2]
option1 = value1
option2 = value2
Unfortunately this appears to be failing as I need to add a secondary level of nesting for the loop to somehow loop over sections in the outer loop and then over options/values in the inner one.
Is there a more elegant or "ansibly" (for lack of an Ansible term corresponding to pythonic) way to achieve this than by wrapping one loop level in a role and iterating over section names using, say include_role
, while passing the section name and list of options/values as a variable?
I suppose one alternative could be to "flatten" the dictionary in a way that would yield something that amounts to (YAML):
vars:
inicontents:
- section: section1
key: option1
value: value1
- section: section1
key: option2
value: value2
- section: section2
key: option1
value: value1
- section: section2
key: option2
value: value2
I'd just like to keep it DRY and avoid the duplication of the section name, when clearly the dict would perfectly map onto the "data model" of the INI file.
I don't know of a way to do this with ansible by default other than using your "flatted" version. Fortunately you can have the best of both worlds and write your own filter plugin for flattening the dict for you. Just add somthing like the following to the
filter_plugins
directory in your project directory or in~/.ansible/plugins/filter_plugins
and name it something likefilters.py
:After this you can use the new filter in your project like this:
It helps sometimes if you know python since that way you can write your own plugins for ansible.
EDIT: I will include a much less readable and not recommended solution as well. Since the
loop:
works with json formatted strings and jinja2 is applied to strings in ansible before they're processed you can use jinja logic to create the "flattend" for you directly in the playbook. This solution is a lot uglier and less reusable than writing your own filter but thecnically still works.