Usually when developing an Ansible role, most of the time we need to write a jinja2 template for some configuration file. Speaking from personal experience, I was writing an Elasticsearch role and I needed to add a elasticsearch.yml
jinja2 template. I was struggling a bit, because I had to add all the Elasticsearch group nodes IP addresses into the following line:
discovery.zen.ping.unicast.hosts: ["192.168.10.1", "192.168.10.2", "192.168.10.3"]
After a bit of googling, I found a temporary solution:
discovery.zen.ping.unicast.hosts: ["{{ elasticsearch_hosts }}"]
elasticsearch_hosts: "{{ groups['elasticnodes'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join(', ') }}"
which lead me to the following result:
discovery.zen.ping.unicast.hosts: [192.168.10.1, 192.168.10.2, 192.168.10.3]
We are still missing the double quotes, so I had to make some small adjustments. But first, let’s talk a bit about map
and join
functions.
Prerequisites
- Ansible
map
function
The map
function is allowing us to change every item in a list. So, we can try to extract all IP addresses of an Ansible group with:
{{ groups['elasticnodes'] | map('extract', hostvars, ['ansible_default_ipv4', 'address'])
Note that you can specify an interface rather than the Ansible default ipv4 address, but keep in mind that ansible_default_ipv4
is more reliable since interface names can become unpredictable.
join
function
The join
function is a filter that’s allowing us to join a list of items into a string. Now, that we have IP addresses with the map function, we can concatenate them with double quotes:
{{ groups['elastic'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join('", "') }}
The final result:
discovery.zen.ping.unicast.hosts: ["192.168.10.1", "192.168.10.2", "192.168.10.3"]
Conclusion
In this post, we covered all the needed steps to concatenate a list of IP addresses of an Ansible group with double quotes and space between them. Feel free to leave a comment below and if you find this tutorial useful, follow our official channel on Telegram.