Maitriser les Handlers Ansible
Mise à jour :
Saviez-vous que vos playbooks Ansible peuvent modifier un fichier de configuration sans jamais redémarrer le service concerné ? C’est exactement la mission des handlers : déclencher une action uniquement lorsqu’une tâche annonce un changement. Résultat : déploiements plus rapides, interruptions minimisées, infrastructure toujours cohérente.
Dans ce chapitre, vous verrez comment déclarer, appeler et flusher ces handlers pour qu’ils deviennent un réflexe naturel dans vos playbooks d’automatisation.
Qu’est-ce qu’un handler Ansible ?
Un handler est une tâche Ansible qui ne s’exécute que lorsqu’elle est appelée par une autre tâche qui a modifié l’état d’un système. Par exemple, si une tâche modifie un fichier de configuration, le handler associé sera déclenché pour redémarrer le service concerné.
Pourquoi utiliser les handlers ?
Pourquoi redémarrer systématiquement un service alors qu’aucune ligne de configuration n’a changé ? Les handlers répondent exactement à cette question : ils n’entrent en action qu’après un événement notify, et une seule fois, même si dix tâches l’ont appelé. Résultat : moins d’interruptions, plus d’idempotence, des playbooks plus rapides.
Comment déclarer un handler Ansible ?
Dans un playbook, la section handlers: se place au même niveau que tasks:. Chaque entrée possède un name unique ; c’est cette étiquette que l’on appellera plus tard avec notify.
Une tâche doit signaler un changement ? Elle déclenche le handler indiqué dans notify. Si plusieurs tâches le notifient, l’action ne s’exécute qu’une seule fois à la fin du play, économisant ainsi des redémarrages.
Exemple de déclaration d’un handler pour redémarrer nginx :
- name: Configurer nginx et redémarrer le service hosts: web become: true
tasks: - name: Installer nginx ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf mode: '0644' owner: root group: root notify: Restart nginx # déclenche le handler
handlers: - name: Restart nginx # nom du handler ansible.builtin.service: name: nginx state: restarted
Utilisation de la syntaxe listen
Pour éviter les conflits de noms, vous pouvez utiliser l’alias listen. Cela permet à plusieurs handlers de réagir à la même notification sans se contredire. Par exemple, si vous avez deux handlers pour nginx et apache2, vous pouvez les regrouper sous un même alias :
tasks: - name: Générer la nouvelle conf nginx ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf mode: '0644' owner: root group: root notify: restart_webserver
- name: Générer la nouvelle conf apache2 ansible.builtin.template: src: apache2.conf.j2 dest: /etc/apache2/apache2.conf mode: '0644' owner: root group: root notify: restart_webserver
handlers: - name: Restart nginx ansible.builtin.service: name: nginx state: restarted listen: restart_webserver
- name: Restart apache2 ansible.builtin.service: name: apache2 state: restarted listen: restart_webserver
Dans cet exemple, les deux handlers nginx et apache2 réagissent à la notification restart_webserver. Cela permet de centraliser la gestion des redémarrages web sans multiplier les notifications.
Ordre d’exécution des handlers
L’ordre naturel des handlers
Par défaut, tous les handlers notifiés s’exécutent à la fin du play, une
seule fois, dans l’ordre où ils apparaissent dans la section handlers:
—pas
dans l’ordre des tâches qui les ont appelés. Ainsi, dix tâches peuvent notifier
« Restart nginx », mais le service ne redémarrera qu’une fois, juste avant que
le play ne passe au suivant. C’est ce qu’on appelle l’ordre naturel des
handlers.
Mais attention : si votre playbook contient plusieurs plays, chaque play dispose de sa propre file de handlers. Ainsi, les handlers notifiés dans un play ne seront pas exécutés dans le play suivant, sauf si vous les notifiez à nouveau.
De même, Ansible vide automatiquement la file des handlers :
- après les
pre_tasks
; - après la section
tasks
; - après les rôles (
roles:
ouinclude_role
) ; - après les
post_tasks
.
Chaque vidage concerne uniquement le play courant ; les plays suivants repartent avec une file vide.
Déclencher plus tôt avec meta: flush_handlers
Vous avez besoin qu’un service soit rechargé avant d’enchaîner sur des tests ? Insérez une tâche spéciale :
tasks: - name: Générer la nouvelle conf ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf mode: '0644' owner: root group: root notify: restart_services
- name: Vider la file de handlers meta: flush_handlers # exécute immédiatement les handlers notifiés
- name: Lancer les tests HTTP ansible.builtin.uri: url: http://localhost/health status_code: 200
handlers: - name: Restart nginx # nom du handler ansible.builtin.service: name: nginx state: restarted
meta: flush_handlers
force l’exécution immédiate puis réinitialise la file ;
les notifications suivantes s’accumulent de nouveau jusqu’au prochain flush
(implicite ou manuel). Utilisez-le avec parcimonie pour ne pas multiplier les
redémarrages.
Bonnes pratiques pour les handlers
Bonnes pratiques
- Utiliser un alias listen unique : plusieurs handlers peuvent réagir au même événement sans collision de noms.
- Préférer state: reloaded à state: restarted pour réduire les interruptions lorsque le service le permet.
- Insérer meta: flush_handlers seulement quand une étape (tests, dépendance entre rôles) exige un service déjà rechargé.
- Contrôler la qualité : exécuter régulièrement ansible-lint et un dry-run
ansible-playbook --check
pour savoir quels handlers seraient déclenchés. - Documenter chaque association tâche → handler.
Pièges à éviter
- Flush trop fréquent : chaque appel à meta: flush_handlers rompt l’agrégation et peut provoquer plusieurs redémarrages successifs du même service.
- Noms dupliqués : deux handlers portant le même name entrent en conflit ; seul le premier sera pris en compte.
- Portée mal comprise : un handler n’existe que dans le play courant ; croire qu’il persiste au play suivant conduit à des services restés non rechargés.
Exercices pratiques : Maîtriser les handlers Ansible
Vous savez désormais pourquoi les handlers sont essentiels : ils ne redémarrent un service que lorsqu’une tâche l’exige via notify. Place maintenant à la pratique : un mini-projet pour voir comment Ansible agrège les notifications, déclenche un handler unique et, au besoin, force son exécution avec flush_handlers.
👉 Travaux pratiques : TP 3 : Handlers Ansible ↗
Ces exercices couvrent notamment
- La création d’un playbook contenant plusieurs tâches qui modifient un fichier de configuration et appellent notify.
- La définition d’un handler unique —
Reload Nginx
— placé dans la sectionhandlers:
du même fichier.
Pourquoi pratiquer ?
- Consolider la logique tâche → notify → handler et éviter les redémarrages multiples.
- Identifier, via les logs, les redémarrages superflus pour optimiser vos temps de déploiement.
- Poser les bases d’un workflow DevOps où chaque changement de config trace son impact exact sur les services.
Clonez le dépôt ou suivez les consignes en ligne ; grâce à ces exercices ciblés, vous saurez déclencher les handlers au bon moment, ni trop tôt, ni trop souvent.
Contrôle de connaissances
Pourquoi ce contrôle ?
Cet contrôle va vous permettre de valider vos connaissances sur le sujet abordé dans le guide. Il comporte des QCM, des questions vrai/faux et des réponses ouvertes à un mot.
🕒 Le chronomètre commence dès que vous cliquez sur Démarrer le test. Vous devrez terminer l’examen avant la fin du temps imparti.
🎯 Pour réussir, vous devez obtenir au moins 80% de bonnes réponses.
💡 Je ne fournis pas directement les réponses aux questions. Cependant, si certaines sont complexes, des pistes d’explication pourront être proposées dans le guide ou après l’examen.
Bonne chance ! 🚀
Conclusion
Maintenant que vous maîtrisez les handlers, vous pouvez optimiser vos playbooks Ansible pour qu’ils ne redémarrent les services que lorsque c’est nécessaire. Cela réduit les interruptions, accélère les déploiements et assure une infrastructure toujours cohérente.
On peut passer à la suite avec les les Templates Jinja.