Toujours déclencher l'exécution du gestionnaire dans Ansible

33

J'utilise Ansible pour provisionner mon serveur de développement.

Je veux qu'il démarre toujours certains services pour moi. J'ai des gestionnaires à cet effet, mais quelle est la meilleure façon de déclencher l'exécution du gestionnaire sans condition, par exemple pour que cela fonctionne toujours?

Quelque chose comme ça:

tasks:
    - name: Trigger handler
      run_handler: name=nginx-restart
Slava Fomin II
la source
6
Si vous souhaitez qu'une tâche soit toujours exécutée, vous devez en faire une tâche plutôt qu'un gestionnaire.
Jordan
@Jordan - parfois, vous voudrez peut-être avoir un gestionnaire déclenché conditionnellement dans la plupart des scénarios, sauf celui-ci.
silverdr

Réponses:

61

Si vous devez absolument déclencher un gestionnaire à chaque fois, voici deux options:

1) Exécutez une commande Noop Shell qui sera toujours signalée comme modifiée

-  name: trigger nginx-restart
   command: /bin/true
   notify: nginx-restart

2) utilisez debug avec changed_when: pour déclencher un gestionnaire

-  debug: msg="trigger nginx-restart"
   notify: nginx-restart
   changed_when: true

En outre de la note pour l' option 1 et vérifiez le mode: Vous pouvez utiliser check_mode: nosi vous utilisez la version Ansible 2.2 ou supérieur ou always_run: yessi vous utilisez les versions antérieures à cela pour que la tâche ne soit pas sautée en mode contrôle. D'après mes tests manuels, il semble que les gestionnaires restent en mode de vérification, mais faites attention car votre cas peut différer.

jarv
la source
7
De nos jours, vous pouvez `--force-handlers exécuter des gestionnaires même si une tâche échoue '
conny
5
Oui, mais cela forcera tous les gestionnaires à s'exécuter
jarv
j'ai trouvé ce post utile concernant le statut modifié, qui m'a conduit ici. serverfault.com/a/799282/173002 . ty.
sonjz
Merci, j'ai utilisé l'option 2 et une changed_whenavec plus de logique pour implémenter une tâche non idempotente [qui peut être invoquée plus d'une fois dans certains cas] en tant que gestionnaire plutôt qu'en tant que tâche.
Sammitch
17

Ansible propose plusieurs options pour forcer les gestionnaires:

1) Pour forcer toujours tous les gestionnaires, exécutez ansible-playbook playbook.yml --force-handlers, comme indiqué ici: https://github.com/ansible/ansible/issues/4777

2) Pour forcer les gestionnaires qui ont été notifiés à un point spécifique d'un playbook, vous pouvez utiliser une méta-tâche https://docs.ansible.com/playbooks_intro.html :

tasks: 
  - shell: some tasks go here
  - meta: flush_handlers
  - shell: some other tasks

3) Cependant, il semble que vous souhaitiez simplement vous assurer qu'un service est en cours d'exécution ou redémarré, quel que soit le résultat d'une autre tâche. Dans ce cas, n'utilisez pas de gestionnaire, utilisez une nouvelle tâche qui appelle le servicemodule d'Ansible : http://docs.ansible.com/service_module.html

tasks: 
  - name: ensure ntp is running
    service: name=ntp state=started enabled=yes

  - name: always reload nginx
    service: name=nginx state=reloaded

  - name: always restart MySQL
    service: name=mysql state=restarted
Jeff Widman
la source
1
Le problème avec (3) est que l'on peut avoir plusieurs tâches qui avertissent le gestionnaire, et je ne veux pas que le gestionnaire s'exécute (redémarrage du service) plusieurs fois.
Jonathan Hartley
Plusieurs tâches peuvent notifier le même gestionnaire et le gestionnaire ne s'exécutera qu'une seule fois. C'est tout l'intérêt des gestionnaires.
Jeff Widman
Salut Jeff. Cette réponse consiste à ne pas utiliser de gestionnaires, à spécifier toutes les actions uniquement à l'aide de tâches.
Jonathan Hartley
Désolé, je crains de ne toujours pas comprendre le cas d'utilisation que vous essayez de résoudre ... Peut-être ouvrir une nouvelle question avec un exemple de ce que vous essayez d'accomplir? Si vous ajoutez un commentaire avec un lien, j'essaierai d'y répondre.
Jeff Widman
Je n'ai pas besoin d'une nouvelle question. L'OQ a demandé "Comment puis-je m'assurer qu'un gestionnaire s'exécute TOUJOURS", et cette réponse, partie 3, a suggéré "Utiliser des tâches à la place", et mon commentaire souligne "Votre tâche peut ensuite s'exécuter plusieurs fois dans certaines circonstances."
Jonathan Hartley
6

Redémarrer un service est une chose; s'assurer qu'il fonctionne est une autre. Si vous voulez ansiblepour vous assurer nginxest en cours d' exécution, vous faites ceci:

tasks:
  - name: Ensure nginx is running
    service: name=nginx state=started
Antonis Christofides
la source