Running a playbook on multiple host groups one at a time

China☆狼群 提交于 2019-11-29 21:56:16

问题


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:

回答1:


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



回答2:


Building off of Konstantin's idea, you can do something like this using aliases and a list of patterns:

---
- hosts: "*-server-batch-1,*-servers-batch-2,*-server-batch-3"
  serial: 3
  ...
...


[london]
london-server-batch-1 ansible_host=server1.london.com
london-server-batch-2 ansible_host=server2.london.com
london-server-batch-3 ansible_host=server3.london.com

[tokyo]
tokyo-server-batch-1 ansible_host=server1.tokyo.com
tokyo-server-batch-2 ansible_host=server2.tokyo.com
tokyo-server-batch-3 ansible_host=server3.tokyo.com


来源:https://stackoverflow.com/questions/44651877/running-a-playbook-on-multiple-host-groups-one-at-a-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!