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

8

Eu tenho um manual que se parece com isso:

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

- hosts: group2
  roles:
    - role2
    - role3

Agora, digamos que eu tenha um arquivo de hosts que tenha uma entrada como esta:

[group1]
host1.example.com

[group2]
host1.example.com

O Ansible executará as tarefas no papel2 DUAS vezes para o host1.exemplo.com, porque ele aparece em dois grupos e cada um tem o papel2 atribuído a eles.

Como posso fazer o Ansible perceber que ele tem o mesmo papel incluído duas vezes e, portanto, só deve executá-lo uma vez?

    
por Asfand Qazi 10.02.2015 / 14:43

2 respostas

9

Como mencionado, isso ocorre por design. Ansible executa apenas uma jogada por vez. Sua cartilha consiste em duas jogadas (os dois itens na lista YAML de nível raiz definidos pelo arquivo de manual). A primeira jogada aplica o papel1 e o papel2 ao grupo1. Essa jogada é executada primeiro e, quando acaba, a segunda jogada começa. Mas a Ansible não tenta unir as peças logicamente. Afinal, você pode querer que as tarefas no role2 sejam executadas duas vezes.

Quanto a abordar o problema, há algumas maneiras de contornar isso, e você escolherá dependerá dos detalhes dos grupos e das funções.

Se todas as tarefas em role2 forem idempotentes, ou seja, se puderem ser executadas várias vezes e terminarem com o mesmo resultado todas as vezes, tudo o que você realmente está perdendo é tempo e não há problema em permitir que os papéis se repitam. Se os papéis demorarem muito tempo para serem aplicados ou se você não puder torná-lo idempotente, considere as seguintes ideias:

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

---
- hosts: group1
  roles:
    - role1

- hosts: group1:group2
  roles:
    - role2

- hosts: group2
  roles:
    - role3

Ou, se as 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ê poderia criar o grupo em seu arquivo de inventário assim:

[group1and2:children]
group1
group2

Em seguida, no seu manual, você pode dividir novamente em três execuções, mas use o terceiro grupo para evitar a repetição de funções:

---
- 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.

    
por 10.02.2015 / 17:31
3

Isso é por design. O único caminho a seguir seria aplicar o role2 somente em um playbook a um grupo específico, e não usar o role2 em nenhum outro livro de um grupo que possa ter membros comuns, como aqui.

    
por 10.02.2015 / 15:06

Tags