I'm looking for a non-ugly way to extract a list of particular values from a list of maps in Ansible. I can find some ways to do it, for example here: here, but everything I have seen is very ugly, and it feels like there should be a way where it is clearer what is being done to someone reading it in future. I could write a filter, but it feels like this should be unnecessary since this must come up relatively regularly.
I have a data structure like so in Ansible:
interfaces:
- name: eth0
subnet: 192.168.2
netmask: 255.255.255.0
static_dhcp_hosts:
- {name: "hosta", mac: "00:01:02:03:04:05", ip: "192.168.2.20"}
- name: eth1
subnet: 192.168.5
netmask: 255.255.255.0
static_dhcp_hosts:
- {name: "hostb", mac: "00:02:03:04:05:06", ip: "192.168.5.20"}
- {name: "hostc", mac: "00:03:04:05:06:07", ip: "192.168.5.21"}
I'd like to get a space separated list of the interface names, so
eth0 eth1
Obviously this is just example data, the actual top level list has 10 elements for one host. I know that I can use the join filter to get from a list of interfaces to the string I want and how to do that.
Can anyone suggest a nice way to make the list, that is readable to future maintainers (code/configuration should be self-documenting as far as possible (and no further))?
I am looking to do something like
{% for interface in interfaces %}{{ interface.name }} {% endfor %}
or
" ".join([ interface['name'] for interface in interfaces ])
in Python.
but, AFAIK, you can't, or it is considered bad practice to, use jinja2 loops like this in a role's task/main.yml, and, as I said, it feels like it shouldn't be necessary to use a custom filter for this.
(This role isn't just configuring a DHCP server, so please don't just suggest a pre-existing role that does that, that wouldn't solve my issue).
Any non-ugly way to do this would be much appreciated, as would confirmation from people that there is no non-ugly way.
I am using Ansible 2.3, but I'm interested in answers still even if they only work in later versions.
Edit:
The following:
"{{ internal_interfaces | items2dict(key_name='name',value_name='name') | list | join(\" \") }}"
works, and is the least ugly I can think of. It makes a dictionary from the list, with both the key and values being from the name attribute of the dictionaries in the list, and then casts this dictionary to a list, which just gives a list of keys. I'd still like something less obtuse and ugly if anyione can think of anything, or for any Ansible gurus to reply if they think there is nothing nicer.