How does merging hashes work?
I’ve set “hash_behaviour=merge” in my ansible.cfg file. So my hashes should merge. But they don’t. Or at least, not in a way that makes sense to me. Here’s pretty much what I have:
file: group_vars/testgroup
stuff:
substuff:
- path: /b/a/c
owner: root
group: root
recurse: no
- path: /for/the/breakfast
owner: someone
group: root
recurse: no
file: host_vars/testserver
stuff:
substuff:
- path: /another/dir
owner: root
group: root
recurse: no
- path: /yet/another/dir
owner: someone
group: root
recurse: no
testserver is in the testgroup.
What I expect is to get all 4 directories created or modified. What I get is only the directories in the host_vars file.
Now, if I do something like:
file: group_vars/testgroup
stuff:
substuff:
blah: this is blah
blah2: this is blah2
file: host_vars/testserver
stuff:
substuff:
blah3: this is blah3
blah4: this is blah4
I do get all four “blah”'s. But that syntax is rather bad for adding things like owner and group…
So, why doesn’t the first one work?
If the sub-entries are dictionaries, they will be merged as well. The issue appears that the substuff entry is a list, so it’s just re-assigning/copying those entries. If you make substuff a dictionary, I believe this will work as you expect.
Yeah, I just figured out that the ‘-’ indicates a list…
The problem is that when I switch to something like:
nfs_automount:
mountpoints:
adminshare:
path: /path/to/dir/
owner: root
group: root
mode: 755
recurse: no
test:
path: /mounts/test/
owner: root
group: root
mode: 755
recurse: no
And try to run a task like:
name: ensure nfs mountpoints exist
file: path={{ nfs_automount.mountpoints[item].path }} state=directory group={{ nfs_automount.mountpoints[item].group }} owner={{ nfs_automount.mountpoints[item].owner }} mode={{ nfs_automount.mountpoints[item].mode }}
with_items: nfs_automount.mountpoints|default()
notify: restart nfs_automount
tags: nfs_automount
It errors saying: with_items expects a list.
So, I need a list in order to loop through the items. But I need a dictionary in order to merge things…
What I’d like to do is have some group values in the group_vars file, but be able to override/add to them in the host_vars file.
Is there a decent way I can do that? Or do I just need to copy the vars from group_vars into host_vars when I need to add/override them?
Well, it took some experimenting, but I figured it out thanks to https://groups.google.com/d/msg/ansible-project/M-FNUK9Wz98/1wF23CZ-6pIJ
To summarize, I had to pass the dictionary to dictsort so that it would create a list. Then I had to figure out the correct syntax to reference the values. Below is what I ended up with.
- name: ensure nfs mountpoints exist
file: path={{ item[1].path }} state=directory group={{ item[1].group }} owner={{ item[1].owner }} mode={{ item[1].mode }}
with_items: nfs_automount.mountpoints|dictsort
notify: restart nfs_automount
tags: nfs_automount