Utilisation de 'delegate_to' dans Ansible
Mise à jour :
Dans un playbook Ansible, chaque tâche s’exécute par défaut sur l’hôte ciblé.
Mais que faire lorsqu’une tâche doit s’exécuter sur un autre hôte, comme le
serveur de contrôle ou un serveur central ? C’est là qu’intervient
delegate_to
. Cette directive permet de déléguer l’exécution d’une tâche à un
autre hôte que celui initialement visé. Elle est idéale pour les actions
centralisées : récupérer un fichier, envoyer une alerte, ou appliquer une
configuration partagée. Grâce à delegate_to
, vous gagnez en souplesse, en
centralisation, et en efficacité opérationnelle dans vos automatisations.
Pourquoi utiliser delegate_to
Automatiser l’exécution de tâches sur un hôte différent avec delegate_to
n’est
pas juste une astuce technique. C’est une méthode puissante pour gagner en
efficacité, fiabilité et lisibilité dans vos workflows d’automatisation.
Centraliser l’exécution des opérations critiques
Imaginez que vous deviez générer un fichier de configuration ou télécharger un
binaire depuis Internet. Faut-il vraiment répéter cette action sur tous les
serveurs ? delegate_to
vous permet de centraliser l’exécution sur un hôte
précis, souvent le serveur de contrôle (localhost
), pour ensuite diffuser
le résultat aux autres machines.
Exemple typique :
- name: Télécharger l'archive sur le serveur de contrôle ansible.builtin.get_url: url: https://monfichier.com/outil.tar.gz dest: /tmp/outil.tar.gz delegate_to: localhost
Cette méthode :
- Évite les duplications de téléchargement
- Réduit la bande passante utilisée
- Sécurise les connexions sortantes (un seul point de sortie)
Simplifier la gestion des tâches conditionnelles
Certaines tâches ne doivent être exécutées qu’une fois, mais profiter à tous les
hôtes. Avec delegate_to
combiné à run_once
, vous pouvez conditionner cela
proprement :
- name: Générer une clé SSH commune pour tous les nœuds ansible.builtin.command: ssh-keygen -t rsa -b 4096 -f /tmp/id_rsa -N '' delegate_to: localhost run_once: true
Ici, un certificat est généré une fois, puis distribué. Cela évite les conflits et standardise la configuration.
Séparer les responsabilités entre hôtes
Vous pouvez définir clairement les rôles de chaque machine dans vos infrastructures IaC :
- Le nœud de contrôle fait les opérations critiques
- Les nœuds cibles appliquent simplement la configuration
Cela favorise la modularité des playbooks et améliore la lisibilité du code Ansible.
Gagner en sécurité
Limiter l’exécution de certaines commandes sensibles à un hôte de confiance
(comme localhost
) renforce la sécurité :
- Pas de duplication de secrets sur chaque hôte
- Moins d’expositions réseau
- Moins de privilèges nécessaires sur les serveurs
Utiliser delegate_to
, c’est donc combiner efficacité, cohérence et
sécurité dans vos automatisations Ansible, tout en structurant vos
tâches dans une logique claire d’infrastructure as code.
Syntaxe de base & mise en place
La directive delegate_to
s’emploie sur une tâche pour indiquer à Ansible
d’exécuter une commande sur un hôte différent de celui ciblé par le playbook.
C’est une syntaxe simple mais puissante, qui peut changer profondément la
logique de vos déploiements.
Voici un exemple de base pour déléguer une tâche au serveur de contrôle
(localhost
) :
- hosts: all tasks: - name: Créer un fichier localement ansible.builtin.file: path: /tmp/fichier_test.txt state: touch delegate_to: localhost
Même si le playbook vise tous les hôtes, la tâche s’exécute uniquement sur localhost.
Combiner delegate_to
avec run_once
Lorsque vous voulez exécuter une tâche une seule fois dans un playbook qui
cible plusieurs hôtes, la combinaison run_once: true
et delegate_to
devient
essentielle. Elle permet d’éviter l’exécution répétée d’une tâche qui ne doit se
produire qu’une fois.
- name: Générer une clé SSH commune pour tous les nœuds ansible.builtin.command: ssh-keygen -t rsa -b 4096 -f /tmp/id_rsa -N '' delegate_to: localhost run_once: true
Ainsi, la génération se fait une seule fois sur localhost
, quel que soit
le nombre de nœuds ciblés.
Utilisation dans les boucles (loop
ou with_items
)
Par défaut, quand vous bouclez sur une liste dans Ansible, la tâche est exécutée
pour chaque élément sur chaque hôte. Avec delegate_to
, cette logique peut être
recentrée sur un hôte unique.
- name: Créer des fichiers de logs d’inventaire ansible.builtin.copy: content: "Machine : {{ item }}" dest: "/tmp/log_{{ item }}.txt" loop: "{{ groups['all'] }}" delegate_to: localhost run_once: true
Cela permet par exemple de générer des rapports pour tous les hôtes depuis un point central, sans les contacter individuellement.
Filtrage dynamique avec when
+ delegate_to
Il est possible d’exécuter une tâche déléguée uniquement si certaines conditions sont remplies :
- name: Recharger HAProxy si on est sur le maître ansible.builtin.service: name: haproxy state: reloaded delegate_to: "{{ inventory_hostname }}" when: "'haproxy-master' in group_names"
Cette souplesse offre une logique conditionnelle puissante, en évitant des duplications de tâches dans les playbooks.
Cas d’usage courants
Utiliser delegate_to
dans Ansible devient incontournable dans plusieurs
situations où la centralisation de tâches est bénéfique. Voici des cas concrets
pour illustrer son utilité et son efficacité dans des scénarios réels.
Téléchargement local de fichiers
Plutôt que de télécharger un fichier depuis Internet sur chaque hôte cible, il est bien plus efficace de le faire une seule fois sur le serveur de contrôle :
- name: Télécharger une archive depuis Internet ansible.builtin.get_url: url: https://example.com/outil.tar.gz dest: /tmp/outil.tar.gz delegate_to: localhost
Ensuite, on peut copier cette archive sur chaque serveur avec une tâche
classique copy
.
Génération de configuration avec Jinja2 centralisée
Certains fichiers de configuration doivent être générés dynamiquement, mais leur création ne dépend que d’un seul point de vue (par exemple, un fichier YAML d’inventaire global). Dans ce cas, on peut centraliser la génération :
- name: Générer le fichier de configuration Nginx ansible.builtin.template: src: nginx.j2 dest: /tmp/nginx.conf delegate_to: localhost run_once: true
Puis, ce fichier est ensuite distribué aux serveurs Nginx.
Exécution de scripts SQL depuis le contrôleur
Si vous gérez plusieurs bases de données mais que vous centralisez les accès via un tunnel SSH ou un hôte bastion, vous pouvez exécuter une requête SQL depuis une seule machine :
- name: Appliquer un script SQL ansible.builtin.command: psql -h db.example.com -U admin -f /tmp/mise_a_jour.sql delegate_to: bastion
Cela limite la surface d’exposition du mot de passe ou des accès sensibles.
Collecte de données et reporting
Quand vous voulez générer un rapport d’état, une sauvegarde, ou un audit de configuration, vous pouvez rassembler les informations des hôtes cibles, puis traiter ou stocker les résultats centralement :
- name: Stocker les résultats d’audit localement ansible.builtin.copy: content: "{{ audit_result }}" dest: "/var/log/audits/{{ inventory_hostname }}.log" delegate_to: localhost
Chaque hôte envoie son résultat, mais l’enregistrement est centralisé sur
localhost
.
Contrôle de connectivité réseau
Vous pouvez tester la connectivité entre le serveur de contrôle et un hôte cible, ou entre deux hôtes, sans installer quoi que ce soit sur les machines :
- name: Vérifier la connectivité SSH vers un serveur ansible.builtin.wait_for: host: 10.0.0.5 port: 22 timeout: 10 delegate_to: localhost
Cela s’avère très utile dans des workflows de validation de disponibilité, ou avant un déploiement automatisé.
Cas d’usage avancés
Dans des environnements plus complexes, delegate_to
devient un outil clé pour
gérer des tâches critiques de manière centralisée et sécurisée. Voici quelques
scénarios avancés où cette directive brille par son efficacité.
Mise à jour DNS centralisée
Lorsqu’un changement dans l’infrastructure nécessite une mise à jour DNS (ex. ajout d’une nouvelle IP), cela doit se faire depuis un serveur DNS maître, et non depuis chaque hôte.
- name: Mettre à jour une entrée DNS via nsupdate ansible.builtin.command: nsupdate /tmp/update.zone delegate_to: dns-master run_once: true
Cette action permet de centraliser les changements DNS tout en maintenant un playbook simple et lisible.
Agrégation de logs vers un serveur central
Au lieu de transmettre les logs individuellement à un SIEM ou un système distant, chaque hôte peut déléguer l’envoi à un collecteur central :
- name: Transférer les logs au serveur central ansible.builtin.copy: src: /var/log/syslog dest: "/srv/logs/{{ inventory_hostname }}.log" delegate_to: logs-collector
Cela renforce la cohérence des journaux et simplifie l’analyse.
Génération et distribution de certificats TLS
Un serveur d’autorité interne peut être responsable de générer les certificats. Vous pouvez ainsi déléguer cette tâche à cet hôte unique, et distribuer ensuite les certificats aux machines concernées.
- name: Générer un certificat TLS ansible.builtin.command: /usr/local/bin/gen-cert.sh {{ inventory_hostname }} delegate_to: ca-server run_once: false
Basculement de base de données automatisé
Lors d’un failover, une tâche de promotion peut être lancée depuis un hôte central :
- name: Promouvoir le nouveau master PostgreSQL ansible.builtin.shell: patronictl switchover --master db1 --candidate db2 delegate_to: pg-controller run_once: true
Cela permet une gestion centralisée et fiable du cluster.
Synchronisation de sauvegardes
Plutôt que chaque serveur pousse sa sauvegarde, vous pouvez les récupérer depuis un serveur de sauvegarde unique :
- name: Récupérer les dumps SQL ansible.builtin.synchronize: src: "/srv/db/{{ inventory_hostname }}.sql" dest: "/mnt/backups/" mode: pull delegate_to: backup-server
Le mode pull
permet de garder le contrôle centralisé sur les transferts.
Mise à jour de configuration HAProxy
Vous pouvez construire une configuration haproxy.cfg
sur un serveur central,
la tester, puis la propager :
- name: Générer le fichier haproxy.cfg ansible.builtin.template: src: haproxy.j2 dest: /tmp/haproxy.cfg delegate_to: haproxy-controller run_once: true
Tests de charge post-déploiement
Une fois l’application déployée, vous pouvez exécuter un test de charge via ab
(Apache Bench) depuis une machine dédiée :
- name: Lancer un test de performance ansible.builtin.command: ab -n 1000 -c 10 http://app.example.com/ delegate_to: bench-runner run_once: true
Bonnes pratiques delegate_to
L’usage de delegate_to
dans Ansible ouvre la voie à une gestion plus fine et
centralisée de vos automatisations. Mais pour éviter les pièges classiques et
garantir un fonctionnement cohérent en production, il est essentiel d’adopter
certaines bonnes pratiques. Voici les recommandations essentielles pour
tirer le meilleur parti de cette fonctionnalité.
Toujours utiliser les FQDN dans delegate_to
Pour éviter les erreurs de résolution DNS ou les confusions dans l’inventaire,
utilisez systématiquement les noms d’hôtes complets (FQDN) dans
delegate_to
. Cela garantit que la tâche est bien dirigée vers l’hôte prévu,
sans ambiguïté.
- name: Redémarrer HAProxy sur le nœud principal ansible.builtin.service: name: haproxy state: restarted delegate_to: haproxy1.example.local
Cela évite les conflits dans des environnements multi-réseaux ou hybrides.
Coupler delegate_to
avec run_once
quand nécessaire
Lorsque vous exécutez une tâche unique mais centrale, n’oubliez pas
d’ajouter run_once: true
pour empêcher la duplication sur plusieurs hôtes.
- name: Générer un token d’authentification ansible.builtin.command: /usr/bin/gen-token.sh delegate_to: auth.example.local run_once: true
Sans run_once
, la tâche serait lancée pour chaque hôte ciblé, même si
delegate_to
l’exécute toujours au même endroit.
Documenter la logique de délégation
Ajoutez des commentaires clairs dans vos tâches utilisant delegate_to
, pour
indiquer le but de la redirection. Cela facilite la maintenance et la
compréhension pour les autres administrateurs.
# Cette tâche est centralisée sur le serveur de contrôle# pour éviter les téléchargements multiples- name: Télécharger une archive une seule fois ansible.builtin.get_url: url: https://example.com/outil.tar.gz dest: /tmp/outil.tar.gz delegate_to: control-node.example.local run_once: true
Tester systématiquement sur un environnement de staging
La combinaison delegate_to
et run_once
peut parfois produire des
comportements inattendus si mal utilisée. Testez toujours vos playbooks dans
un environnement de préproduction avant de les exécuter en production.
Contrôle de connaissances : Inventaires statiques Ansible
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
delegate_to
permet de centraliser l’exécution des tâches dans Ansible,
en les déléguant à un hôte spécifique comme le contrôleur ou un serveur
central. C’est un outil simple mais puissant, qui améliore la lisibilité, la
sécurité et l’efficacité des playbooks. Utilisé avec soin – en
particulier avec run_once
et des FQDN explicites – il devient
indispensable dans toute stratégie Infrastructure as Code moderne.