Ansible:一个主机出现在多个组中,并且两个组中都有相同的任务;有什么办法可以运行一次任务吗?

Asf*_*azi 9 ansible

我有一本看起来像这样的剧本:

---
- hosts: group1
  roles:
    - role1
    - role2

- hosts: group2
  roles:
    - role2
    - role3
Run Code Online (Sandbox Code Playgroud)

现在说我有一个主机文件,它有这样的条目:

[group1]
host1.example.com

[group2]
host1.example.com
Run Code Online (Sandbox Code Playgroud)

Ansible 将在 host1.example.com 的 role2 中运行任务两次,因为它出现在 2 个组中,并且每个组都分配了 role2。

我怎样才能让 Ansible 意识到它包含两次相同的角色,因此它应该只运行一次?

dav*_*ams 10

如前所述,这是设计使然。Ansible 一次只执行一个 play。你的剧本由两个剧本组成(剧本文件定义的根级 YAML 列表中的两个项目)。第一个剧本将role1 和role2 应用于group1。该剧首先执行,只有当它完成后,第二部剧才会开始。但是 Ansible 并没有尝试在逻辑上将这些剧本合并在一起。毕竟,您可能实际上希望 role2 中的任务运行两次。

至于解决这个问题,有几种方法可以解决这个问题,您选择哪种方法取决于组和角色的详细信息。

如果 role2 中的所有任务都是幂等的,即如果它们可以运行多次并且每次都得到相同的结果,那么你真正失去的只是时间,让角色重复是可以的。如果角色需要很长时间才能应用,或者如果您无法使其具有幂等性,请考虑以下想法:


您可以将剧本分成三个剧本,并分别应用角色:

---
- hosts: group1
  roles:
    - role1

- hosts: group1:group2
  roles:
    - role2

- hosts: group2
  roles:
    - role3
Run Code Online (Sandbox Code Playgroud)

或者,如果您的角色需要组合在一起,您可以为需要所有三个角色的服务器创建第三个组。你不需要把他们从其他两组中剔除。您可以在您的清单文件中创建该组,如下所示:

[group1and2:children]
group1
group2
Run Code Online (Sandbox Code Playgroud)

然后在你的剧本中,你可以再次分成三场比赛,但使用第三组以避免重新运行角色:

---
- hosts: group1:!group1and2
  roles:
    - role1
    - role2

 - hosts: group1and2
   roles:
     - role1
     - role2
     - role3

 - hosts: group2:!group1and2
   roles:
     - role2
     - role3
Run Code Online (Sandbox Code Playgroud)

这很丑陋,但在某些情况下可能很有用。