Ansible: un hôte apparaît dans plusieurs groupes, et les deux groupes ont les mêmes tâches en eux; une façon d'exécuter des tâches une fois?

9

J'ai un playbook qui ressemble à ceci:

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

- hosts: group2
  roles:
    - role2
    - role3

Maintenant, disons que j'ai un fichier d'hôtes qui a une entrée comme celle-ci:

[group1]
host1.example.com

[group2]
host1.example.com

Ansible exécutera les tâches dans le rôle2 DEUX FOIS pour host1.example.com car il apparaît dans 2 groupes et chacun a un rôle2 qui leur est affecté.

Comment puis-je faire en sorte qu'Ansible se rende compte qu'elle a le même rôle inclus deux fois, et qu'elle ne devrait donc l'exécuter qu'une seule fois?

Asfand Qazi
la source
Il serait préférable de nous donner de vrais exemples au lieu de "rôle1", "rôle2" etc., car peut-être devriez-vous le faire différemment. Mais cela dépend de ce que vous essayez réellement de réaliser.
Antonis Christofides

Réponses:

10

Comme mentionné, c'est par conception. Ansible exécute une seule lecture à la fois. Votre playbook se compose de deux jeux (les deux éléments de la liste YAML au niveau racine définie par le fichier du playbook). Le premier jeu applique le rôle1 et le rôle2 au groupe1. Ce jeu s'exécute en premier et ce n'est que lorsqu'il est terminé que le deuxième jeu commence. Mais Ansible n'essaie pas de fusionner les pièces ensemble de manière logique. Après tout, vous souhaiterez peut-être que les tâches du rôle 2 s'exécutent deux fois.

En ce qui concerne le traitement du problème, vous pouvez contourner ce problème de plusieurs manières, et celle que vous choisirez dépendra des détails des groupes et des rôles.

Si toutes les tâches du rôle 2 sont idempotentes, c'est-à-dire si elles peuvent être exécutées plusieurs fois et se retrouver avec le même résultat à chaque fois, alors tout ce que vous perdez est le temps, et il est normal de laisser les rôles se répéter. Si les rôles prennent beaucoup de temps à appliquer ou si vous ne pouvez pas les rendre idempotents, envisagez les idées suivantes:


Vous pouvez diviser le livre de jeu en trois jeux et appliquer les rôles individuellement:

---
- hosts: group1
  roles:
    - role1

- hosts: group1:group2
  roles:
    - role2

- hosts: group2
  roles:
    - role3

Ou si vos rôles doivent être regroupés, vous pouvez créer un troisième groupe pour les serveurs qui ont besoin des trois rôles. Vous n'avez pas besoin de les retirer des deux autres groupes. Vous pouvez créer le groupe dans votre fichier d'inventaire comme ceci:

[group1and2:children]
group1
group2

Ensuite, dans votre livre de jeu, vous pouvez à nouveau vous diviser en trois jeux, mais utilisez le troisième groupe pour éviter de réexécuter les rôles:

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

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

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

C'est assez moche mais cela peut être utile dans certains cas.

daveadams
la source
Merci, je pense que j'irai avec une variante de l'option (2) - Je vais rendre mes groupes et rôles plus granulaires pour regrouper mes serveurs.
Asfand Qazi
Si j'appelle des hôtes via une variable en tant que {{host1}} et {{host2}}, comment puis-je les regrouper?
BMW
Si vous recherchez la section de documentation: Modèles courants
Sahap Asci
3

C'est par conception. La seule façon de procéder serait d'appliquer le rôle2 uniquement dans un livre de jeu à un groupe spécifique, et de ne pas utiliser le rôle2 dans aucun autre livre de jeu d'un groupe qui pourrait avoir des membres communs, comme ici.

Serge van Ginderachter
la source