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

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

我有一本类似这样的剧本:

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

- hosts: group2
  roles:
    - role2
    - role3

现在假设我有一个 hosts 文件,其中有如下条目:

[group1]
host1.example.com

[group2]
host1.example.com

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

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

答案1

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

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

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


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

---
- hosts: group1
  roles:
    - role1

- hosts: group1:group2
  roles:
    - role2

- hosts: group2
  roles:
    - role3

或者,如果您的角色需要分组在一起,您可以为需要所有三个角色的服务器创建第三个组。您不需要将它们从其他两个组中取出。您可以在清单文件中像这样创建组:

[group1and2:children]
group1
group2

然后,您可以在剧本中再次分成三个剧本,但使用第三组来避免重复角色:

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

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

 - hosts: group2:!group1and2
   roles:
     - role2
     - role3

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

答案2

这是设计使然。唯一的办法是仅在一个剧本中将 role2 应用于一个特定组,而不是在可能有共同成员的组的任何其他剧本中使用 role2,就像这里一样。

相关内容