tl;dr: is there a way to make with_subelements work with dicts? Or something to that effect?
I’ve been trying to figure out how to run a task over a dict, that also loops over a nested dict in order to run the actual commands.
So far, I haven’t figured out how to use with_items, with_dict, or with_nested to do what I want. with_subelements comes close, but keeps choking on the fact my subelement is not a list.
My playbook (would have pastebined it, but pastebin wouldn’t load for me…):
testing playbook
- hosts: 192.168.88.2
vars:
people:
johnsmith:
fname: john
lname: smith
locations:
birthplace:
state: id
city: boise
second:
state: or
city: portland
third:
state: ha
city: honolulu
jilljones:
fname: jill
lname: jones
locations:
birthplace:
state: mo
city: springfield
second:
state: mt
city: fort benton
third:
state: id
city: emmett
jilljones:
locations:
birthplace:
state: wa
city: wilbur
tasks:- name: testing dict
debug: msg=“{{ item.1 }}”
with_subelements:- people
- locations
The output:
$ ansible-playbook -i hosts -u vagrant --sudo tmp/testing.yml
PLAY [192.168.88.2] ***********************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.88.2]
TASK: [testing dict] **********************************************************
fatal: [192.168.88.2] => the key locations should point to a list, got ‘{‘birthplace’: {‘city’: ‘boise’, ‘state’: ‘id’}, ‘second’: {‘city’: ‘portland’, ‘state’: ‘or’}, ‘third’: {‘city’: ‘honolulu’, ‘state’: ‘ha’}}’
FATAL: all hosts have already failed – aborting
PLAY RECAP ********************************************************************
to retry, use: --limit @/home/reagand/testing.retry
192.168.88.2 : ok=1 changed=0 unreachable=1 failed=0
What I want to see is something like:
johnsmith:
birthplace:
state: id
city: boise
second:
state: or
city: portland
third:
state: ha
city: honolulu
jilljones:
birthplace:
state: wa
city: wilbur
second:
state: mt
city: fort benton
third:
state: id
city: emmett
I really need this to be a dict/hash so that hash_behaviour=merge works. For example, if I want jilljones birthplace to default to springfield, mo, in group_vars, but for a specific host it should be seattle, wa, then I would set the following in the specific host_vars file:
people:
jilljones:
locations:
birthplace:
city: seattle
state: wa
Note, I’ve only been using this people hash as something to experiment on. My actual use case is a task that sets configuration settings for a web app. The app config didn’t lend itself to templating. I tried that first. Now I’ve ended up with lininfile regex replacements, each named with their own key. Something like:
configkey:
regex:
value:
configkey2:
regex:
value:
…
That’s the equivalent of the locations hash in my testing playbook.
I also don’t know how many instances of the app I’ll have per server, so I can’t just do a task per instance.
Ultimately, if I make my subelement a list, http://pastebin.com/mixMTz6H (pastebin worked earlier…) it works, but it overrides all the previously set subelements of the main key. That means I have to copy all the locations from group_vars into host_vars if I want to override something on a specific host. I’d prefer to avoid that. So, is there a with_subelements that would work with a hash like I want? Or another way to get the same effect?