I want to run a playbook containing some roles on multiple host groups I create dynamically with the group_by module.
I'm able to do it like the example below (ping replacing my actual role).
I was wondering if there is a way to run each group separately in a loop instead of listing all instance ids. I don't want to create a duplicate line with every instance id.
The purpose here is to deploy to one instance in every data center at a time instead of running all with a low serial which takes a long time.
There might be a different way of doing it, I don't want to create static groups in the inventory for each instance_id as well.
---
- hosts: tag_type_edgenode
tasks:
- group_by: key=instance_id_{{instance_id}}
register: dyn_groups
- hosts: instance_id_1
tasks:
- ping:
- hosts: instance_id_2
tasks:
- ping:
- hosts: instance_id_3
tasks:
- ping:
- hosts: instance_id_4
tasks:
- ping:
If you have equal count of hosts in each group, you can use pattern + serial.
Ansible forms host list by pattern moving through groups sequentially. So if you have equal count of hosts, then batches formed by serial will be equal to groups.
In your example, if you have exactly 3 hosts in each group, you can use:
- hosts: instance_id_*
serial: 3
tasks:
- ping:
If you don't mind a bit of Ansible patching, you can modify _get_serialized_batches method.
Add this code just before while len(all_hosts) > 0:
:
if 'serialize_by_var' in play.get_vars():
param = play.get_vars()['serialize_by_var']
sb = []
def by_param(x):
vrs = x.get_vars()
if param in vrs:
return vrs[param]
else:
return None
s_hosts = sorted(all_hosts,key=by_param)
for k, g in itertools.groupby(s_hosts, by_param):
sb.append(list(g))
display.vv('Serializing by host var "{}": {}'.format(param,sb))
return sb
And you can serialize hosts by any variable like this:
- hosts: tag_type_edgenode
vars:
serialize_by_var: instance_id
tasks:
- ping