运行 一次在多个主机组上的剧本
Running a playbook on multiple host groups one at a time
我想要 运行 一个剧本,其中包含我使用 group_by 模块动态创建的多个主机组中的一些角色。
我可以像下面的例子那样做(ping 代替我的实际角色)。
我想知道是否有一种方法可以 运行 每个组在循环中分开,而不是列出所有实例 ID。我不想为每个实例 ID 创建一个重复的行。
这里的目的是一次部署到每个数据中心的一个实例,而不是 运行用低序列号部署所有实例,这需要很长时间。
可能有不同的方法,我也不想在清单中为每个 instance_id 创建静态组。
---
- 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:
如果每个组中的主机数量相等,则可以使用模式 + 序列号。
Ansible 通过按顺序在组中移动的模式形成主机列表。因此,如果您的主机数量相等,则由串行形成的批次将等于组。
在您的示例中,如果每个组中恰好有 3 个主机,则可以使用:
- hosts: instance_id_*
serial: 3
tasks:
- ping:
如果您不介意 Ansible 补丁,您可以修改 _get_serialized_batches 方法。
在 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
并且您可以像这样通过任何变量序列化主机:
- hosts: tag_type_edgenode
vars:
serialize_by_var: instance_id
tasks:
- ping
根据 Konstantin 的想法,您可以使用别名和模式列表来执行类似的操作:
---
- 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
有一种使用每个组的大小(长度)的更简单的方法。但是,这会在组的所有成员上运行,按顺序流经组。我想 OP 是在问如何对每个组的第一个成员采取行动,我也在研究这个问题。
- name: "Restore selected devices in model_dc"
hosts: group_1, group_2, group_3, group_4, group_5, group_6, group_7, !excluded
any_errors_fatal: true # Stop entire play if one host fails
gather_facts: no
order: inventory
serial:
- "{{ groups['group_1'] | length }}" # The number of hosts for first batch
- "{{ groups['group_2'] | length }}" # The number of hosts for second batch
- "{{ groups['group_3'] | length }}"
- "{{ groups['group_4'] | length }}"
- "{{ groups['group_5'] | length }}"
- "{{ groups['group_6'] | length }}"
- "{{ groups['group_7'] | length }}" # The number of hosts for every batch until the end.
我想要 运行 一个剧本,其中包含我使用 group_by 模块动态创建的多个主机组中的一些角色。
我可以像下面的例子那样做(ping 代替我的实际角色)。
我想知道是否有一种方法可以 运行 每个组在循环中分开,而不是列出所有实例 ID。我不想为每个实例 ID 创建一个重复的行。
这里的目的是一次部署到每个数据中心的一个实例,而不是 运行用低序列号部署所有实例,这需要很长时间。
可能有不同的方法,我也不想在清单中为每个 instance_id 创建静态组。
---
- 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:
如果每个组中的主机数量相等,则可以使用模式 + 序列号。
Ansible 通过按顺序在组中移动的模式形成主机列表。因此,如果您的主机数量相等,则由串行形成的批次将等于组。
在您的示例中,如果每个组中恰好有 3 个主机,则可以使用:
- hosts: instance_id_*
serial: 3
tasks:
- ping:
如果您不介意 Ansible 补丁,您可以修改 _get_serialized_batches 方法。
在 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
并且您可以像这样通过任何变量序列化主机:
- hosts: tag_type_edgenode
vars:
serialize_by_var: instance_id
tasks:
- ping
根据 Konstantin 的想法,您可以使用别名和模式列表来执行类似的操作:
---
- 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
有一种使用每个组的大小(长度)的更简单的方法。但是,这会在组的所有成员上运行,按顺序流经组。我想 OP 是在问如何对每个组的第一个成员采取行动,我也在研究这个问题。
- name: "Restore selected devices in model_dc"
hosts: group_1, group_2, group_3, group_4, group_5, group_6, group_7, !excluded
any_errors_fatal: true # Stop entire play if one host fails
gather_facts: no
order: inventory
serial:
- "{{ groups['group_1'] | length }}" # The number of hosts for first batch
- "{{ groups['group_2'] | length }}" # The number of hosts for second batch
- "{{ groups['group_3'] | length }}"
- "{{ groups['group_4'] | length }}"
- "{{ groups['group_5'] | length }}"
- "{{ groups['group_6'] | length }}"
- "{{ groups['group_7'] | length }}" # The number of hosts for every batch until the end.