In my environment i have a group_vars structure something like the following:
`
[global:children]
datacenter1
[datacenter1:children]
network_zone1
network_zone2
[network_zone1]
server1
[network_zone2]
server2
`
so using a simple case where I want to add entries to /etc/hosts (although there are other use cases, this just seemed the simplest to demonstrate)
I want to be able to set group_vars within each group that get merged/appended together for processing by my role. However
since the default ansible behavior is not to merge and I don’t really want to change the default.
therefore I was thinking about doing something like this:
`
[global:vars]
linux_hosts_entries_global:
- { ip: 123.124.125.125, names: [backup_server]}
[datacenter1:vars]
linux_hosts_entries_dc1:
- { ip: 123.124.125.126, names: [dc1_server]}
[network_zone1:vars]
linux_hosts_entries_z1:
- { ip: 123.124.125.125, names: [z1_server]}
`
Then I could do something like below to loop through the variables to get a merged list.
`
- name: “debug2”
debug:
msg: "value is: {{ lookup(‘vars’, item) }} "
loop: “{{ hostvars[inventory_hostname] | select(‘match’, ‘^linux_hosts_entries’) |list }}”
`
or in the case of a template, you could do something like this:
{% set linux_hosts_merged_entries = hostvars[inventory_hostname] | select('match', '^linux_hosts_entries') |list %} {% for groupvar_name in linux_hosts_merged_entries %} {% set host_entries = lookup('vars', groupvar_name) %} {% for host_entry in host_entries %} {{ host_entry.ip }} {{ host_entry.names | join(' ') }} {% endfor %} {% endfor %}
I was wondering how others are handling similar use cases? is there a simpler solution?
This strategy seems to work quite well.
I am aware of combine/union filters, however these require that you know the names of the variables ahead of time. I like that in this model I can add additional variables later without affecting the existing setup.
I also created a PR to simplify further by adding regex support to the lookup vars plugin.