Resolvido: um host aparece em mais de um grupo e os dois grupos têm as mesmas tarefas; alguma maneira de executar tarefas uma vez?

9

Eu tenho um manual que se parece com isso:

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

- hosts: group2
  roles:
    - role2
    - role3

Agora diga que eu tenho um arquivo de hosts que possui uma entrada como esta:

[group1]
host1.example.com

[group2]
host1.example.com

O Ansible executará as tarefas na função2 DUAS VEZES para host1.exemplo.com, pois aparecerá em 2 grupos e cada uma terá a função2 atribuída a eles.

Como posso fazer com que o Ansible perceba que tem o mesmo papel incluído duas vezes e, portanto, deve executá-lo apenas uma vez?

Asfand Qazi
fonte
Seria melhor nos dar exemplos reais em vez de "role1", "role2" etc., porque talvez você devesse fazer isso de maneira diferente. Mas isso depende do que você está realmente tentando alcançar.
Antonis Christofides

Respostas:

10

Como mencionado, isso ocorre por design. Ansible executa apenas uma jogada de cada vez. Seu manual é composto por duas execuções (os dois itens na lista YAML no nível raiz definida pelo arquivo do manual). A primeira peça aplica role1 e role2 ao grupo1. Essa jogada é executada primeiro e somente quando termina a segunda peça começa. Mas o Ansible não tenta mesclar as peças logicamente. Afinal, você pode realmente querer que as tarefas na role2 sejam executadas duas vezes.

Quanto a resolver o problema, existem algumas maneiras de contornar esse problema e a escolha que você escolher dependerá dos detalhes dos grupos e funções.

Se todas as tarefas no role2 são idempotentes, ou seja, se elas podem ser executadas várias vezes e terminar com o mesmo resultado todas as vezes, tudo o que você realmente está perdendo é tempo, e não há problema em repetir as funções. Se as funções levarem muito tempo para serem aplicadas ou se você não puder torná-la idempotente, considere as seguintes idéias:


Você pode dividir o manual em três peças e aplicar as funções individualmente:

---
- hosts: group1
  roles:
    - role1

- hosts: group1:group2
  roles:
    - role2

- hosts: group2
  roles:
    - role3

Ou, se suas funções precisarem ser agrupadas, você poderá criar um terceiro grupo para os servidores que precisam das três funções. Você não precisa tirá-los dos outros dois grupos. Você pode criar o grupo no seu arquivo de inventário assim:

[group1and2:children]
group1
group2

Em seu manual, você poderá novamente dividir-se em três, mas use o terceiro grupo para evitar reexecutar os papéis:

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

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

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

Isso é muito feio, mas pode ser útil em alguns casos.

daveadams
fonte
Obrigado, acho que vou com uma variação da opção (2) - tornarei meus grupos e funções mais granulares para agrupar meus servidores.
Asfand Qazi
Se eu chamo hosts através da variável como {{host1}} e {{host2}}, como posso reuni-los?
BMW
Se você procurar a seção de documentação: Padrões comuns
Sahap Asci
3

Isso ocorre por design. O único caminho a seguir seria aplicar role2 apenas em um manual a um grupo específico, e não usar role2 em qualquer outro manual em um grupo que possa ter membros comuns, como aqui.

Serge van Ginderachter
fonte