Ansible Dynamic Groups Trick
Here is a handy Ansible task to dynamically create a list of hosts, based on items in an inventory. This was created specifically for a playbook dealing with JBoss EAP
TCP_PING
configurations, but the technique can be applied to various other applications.
Steps
First set an Ansible Fact that will hold the list.
- name: Collect IPs for the entire cluster
set_fact:
list_of_ips: "{{ groups['cluster'] | map('extract', hostvars, ['ansible_default_ipv4', 'address']) | join('[7600],') }}[7600]"
Note that we are also pulling out the ansible_default_ipv4
field out of hostvars
. We’re appending “[7600]” because that’s what JBoss expects the default port to be, but that is not pertinent to what we are doing with Ansible here.
Now that the variable has been set, you can use it anywhere.
- name: Set TCPPING Protocol Configurations
xml:
path: ""
namespaces:
a: urn:jboss:domain:5.0
b: urn:jboss:domain:jgroups:5.0
xpath: "/a:domain/a:profiles/a:profile[@name='']/b:subsystem/b:stacks/b:stack[@name='tcp']/b:protocol[@type='org.jgroups.protocols.TCPPING']/b:property[@name='']"
pretty_print: true
value: ""
loop:
- { name: "initial_hosts", value: ""}
- { name: "port_range", value: "0"}
- { name: "timeout", value: "300000"}
- { name: "num_initial_members", value: ""}
Bonus
There’s a bonus tip here - you can do call length
on the map to get the number of hosts in that particular Ansible group.
The only issue with this task is it expects there to be at least 1 host in the inventory file, which is probably a safe assumption. You could make this more robust and be more defensive.