Ansible: un host aparece en más de un grupo, y ambos grupos tienen las mismas tareas en ellos; alguna forma de ejecutar tareas una vez?

9

Tengo un libro de jugadas que se parece a esto:

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

- hosts: group2
  roles:
    - role2
    - role3

Ahora digamos que tengo un archivo de hosts que tiene una entrada como esta:

[group1]
host1.example.com

[group2]
host1.example.com

Ansible ejecutará las tareas en role2 TWICE para host1.example.com porque aparece en 2 grupos y cada uno tiene role2 asignado.

¿Cómo puedo hacer que Ansible se dé cuenta de que tiene el mismo rol incluido dos veces y, por lo tanto, solo debería ejecutarlo una vez?

Asfand Qazi
fuente
Sería mejor darnos ejemplos reales en lugar de "role1", "role2", etc., porque tal vez debería hacerlo de manera diferente. Pero depende de lo que realmente estés tratando de lograr.
Antonis Christofides

Respuestas:

10

Como se mencionó, esto es por diseño. Ansible ejecuta solo una jugada a la vez. Su libro de jugadas consta de dos jugadas (los dos elementos en la lista YAML de nivel raíz definidos por el archivo del libro de jugadas). La primera jugada aplica role1 y role2 al grupo1. Esa jugada se ejecuta primero, y solo una vez que termina, comienza la segunda jugada. Pero Ansible no intenta fusionar las jugadas lógicamente. Después de todo, es posible que desee que las tareas en role2 se ejecuten dos veces.

En cuanto a abordar el problema, hay algunas maneras en que podría solucionar este problema, y ​​la que elija dependerá de los detalles de los grupos y roles.

Si todas las tareas en role2 son idempotentes, es decir, si se pueden ejecutar varias veces y terminan con el mismo resultado cada vez, entonces todo lo que realmente está perdiendo es tiempo, y está bien permitir que los roles se repitan. Si los roles tardan mucho en aplicarse o si no puede hacerlo idempotente, considere las siguientes ideas:


Podría dividir el libro de jugadas en tres jugadas y aplicar los roles individualmente:

---
- hosts: group1
  roles:
    - role1

- hosts: group1:group2
  roles:
    - role2

- hosts: group2
  roles:
    - role3

O si sus roles deben agruparse, puede crear un tercer grupo para los servidores que necesitan los tres roles. No es necesario sacarlos de los otros dos grupos. Puede crear el grupo en su archivo de inventario de esta manera:

[group1and2:children]
group1
group2

Luego, en su libro de jugadas, podría dividirse nuevamente en tres jugadas, pero use el tercer grupo para evitar volver a ejecutar roles:

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

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

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

Eso es bastante feo, pero puede ser útil en algunos casos.

daveadams
fuente
Gracias, creo que iré con una variación de la opción (2): haré que mis grupos y roles sean más granulares para agrupar mis servidores.
Asfand Qazi
Si llamo hosts a través de variables como {{host1}} y {{host2}}, ¿cómo puedo juntarlos?
BMW
Si busca la sección de documentación: Patrones comunes
Sahap Asci
3

Esto es por diseño. El único camino a seguir sería aplicar role2 solo en un libro de jugadas a un grupo específico, y no usar role2 en ningún otro libro de jugadas en un grupo que pueda tener miembros comunes, como aquí.

Serge van Ginderachter
fuente