Aller au contenu
Infrastructure as Code medium

Async et poll Ansible : tâches longues, fire-and-forget, async_status

11 min de lecture

Logo Ansible

Une tâche Ansible standard bloque la connexion SSH jusqu’à ce qu’elle finisse. Pour une compilation de 30 minutes, un dnf upgrade complet ou un reboot, ce comportement pose deux problèmes : timeout SSH (la connexion lâche) et monopolisation du worker (les autres hôtes attendent). Le mode async détache la tâche du worker — elle tourne en arrière-plan côté managed node, et Ansible la surveille par polling.

Cette page couvre les trois patterns : async + poll > 0 (surveillance synchrone), async + poll: 0 (fire-and-forget), et la combinaison async_status (suivre une tâche async lancée plus tôt).

  • async: : durée maximale d’une tâche en arrière-plan (timeout) ;
  • poll: : intervalle de surveillance (en secondes) ; poll: 0 = fire-and-forget ;
  • async_status : module qui vérifie l’état d’une tâche async à un moment donné ;
  • Le pattern fire-and-forget suivi d’une vérification ultérieure ;
  • Les modules incompatibles avec async (raw, meta).

Imaginez :

- name: Mettre à jour tous les paquets (peut prendre 20 minutes)
ansible.builtin.dnf:
name: "*"
state: latest

Sur un serveur avec 200 paquets à mettre à jour, cette tâche prend 20-30 minutes. SSH coupe la connexion après le ssh_args de default 60s (avec ControlPersist=60s), et le timeout du module fait planter l’opération.

Mode async :

- name: Mettre à jour tous les paquets (async)
ansible.builtin.dnf:
name: "*"
state: latest
async: 1800 # max 30 min côté managed node
poll: 30 # vérifier toutes les 30s

La tâche fork côté managed node, Ansible se déconnecte après le démarrage et revient toutes les 30 secondes pour vérifier l’avancement. La connexion SSH ne reste jamais ouverte plus de quelques secondes.

Pattern 1 — async + poll > 0 : surveillance synchrone

Section intitulée « Pattern 1 — async + poll > 0 : surveillance synchrone »
- name: Build long avec surveillance
ansible.builtin.shell: make -j4
args:
chdir: /srv/build
async: 3600 # max 1 heure
poll: 60 # vérifier toutes les 60s

Le play attend la fin (mais sans monopoliser SSH). C’est le pattern par défaut quand vous ne savez pas si la tâche peut échouer et que vous voulez bloquer si oui.

- name: Lancer un backup en arrière-plan
ansible.builtin.shell: /usr/local/bin/backup.sh
async: 7200 # max 2 heures
poll: 0 # fire-and-forget
register: backup_job

Avec poll: 0, Ansible lance la tâche, récupère un ID de job, et passe immédiatement à la suite. La tâche tourne indépendamment côté managed node. Cas typique : un backup qui doit s’exécuter sans bloquer le déploiement.

Pattern 3 — async_status : suivre une tâche fire-and-forget

Section intitulée « Pattern 3 — async_status : suivre une tâche fire-and-forget »

Pour récupérer le statut d’une tâche fire-and-forget plus tard :

- name: Lancer le backup
ansible.builtin.shell: /usr/local/bin/backup.sh
async: 7200
poll: 0
register: backup_job
# ... d'autres tâches ...
- name: Attendre la fin du backup
ansible.builtin.async_status:
jid: "{{ backup_job.ansible_job_id }}"
register: backup_result
until: backup_result.finished
retries: 60
delay: 60 # 60 retries x 60s = 1h max d'attente

until: backup_result.finished répète la vérification jusqu’à ce que le job soit fini. retries: 60 + delay: 60 autorisent jusqu’à 1 heure d’attente.

Un reboot coupe SSH en plein milieu et ne peut pas être géré comme une tâche normale. Le pattern :

- name: Reboot du système
ansible.builtin.reboot:
msg: "Reboot pour appliquer le nouveau kernel"
reboot_timeout: 300 # attendre max 5 min que SSH revienne
test_command: uptime

Le module ansible.builtin.reboot gère automatiquement :

  1. La déconnexion attendue après le shutdown -r ;
  2. L’attente que SSH revienne (reboot_timeout) ;
  3. La vérification que le système est opérationnel (test_command).

Pas besoin d’asyncreboot est conçu pour ça. Mais le pattern async est utile quand vous voulez lancer un reboot et ne pas attendre (par exemple en mode rolling où chaque hôte reboote indépendamment) :

- name: Reboot fire-and-forget
ansible.builtin.shell: sleep 5 && shutdown -r now
async: 60
poll: 0

Certains modules ne peuvent pas tourner en async :

  • raw : trop bas niveau (pas de Python pour gérer le job)
  • meta : méta-actions internes (flush_handlers)
  • Les modules interactifs (rares)

Ansible vous le signale avec un message clair en cas d’usage incorrect.

ParamètreRôle
async: 3600Côté managed node : tue la tâche si pas finie en 1h
until + retries + delayCôté control node : attend N retries x delay secondes

Les deux limites s’appliquent simultanément — la plus stricte gagne.

Un async en --check se comporte comme une tâche normale en check : il simule sans rien lancer en arrière-plan. Pas de surprise.

SymptômeCauseFix
async_status retourne finished: 0 indéfinimentLe job a été tué par le timeout async:Augmenter async: ou paralléliser le travail
Job fire-and-forget perdu (pas de jid pour le suivre)register: oublié sur la tâche asyncToujours register: var quand poll: 0
Module async qui plante avec module not supportedModule non compatible (raw, meta)Bascule en mode synchrone, ou wrap dans un shell:
until: result.finished plante avec 'NoneType' has no attributeLa première vérif async_status n’a pas encore le jobAjouter register: result à la tâche async_status: (pas la tâche d’origine)
async: 0 (zéro) au lieu de fire-and-forgetasync: 0 = synchrone (ignore async) ; pour fire-and-forget c’est poll: 0Bien mettre async: <timeout> + poll: 0
  • async: <secondes> détache la tâche du worker SSH — Ansible vérifie périodiquement, pas de timeout SSH.
  • poll: <secondes> = surveillance synchrone (le play attend la fin, sans bloquer SSH).
  • poll: 0 = fire-and-forget : Ansible lance la tâche, récupère un ID via register:, et continue.
  • async_status: + until: + retries: + delay: suit une tâche fire-and-forget jusqu’à sa fin.
  • ansible.builtin.reboot gère automatiquement le reboot + reconnexion SSH — pas besoin d’async pour ce cas.
  • Les modules raw et meta ne supportent pas async.

Cette page a un lab d’accompagnement : labs/ecrire-code/async-poll/ dans stephrobert/ansible-training. Il contient un README.md guidé, un Makefile (make verify lance les tests), et un challenge final auto-évalué : lancer un job async (sleep 5) en fire-and-forget puis attendre via async_status.

Une fois le lab provisionné :

Fenêtre de terminal
cd ~/Projets/ansible-training/labs/ecrire-code/async-poll/
cat README.md # tuto pas à pas
cat challenge/README.md # consigne du challenge final
pytest -v challenge/tests/ # lancer les tests testinfra

Si les tests passent, vous maîtrisez les concepts couverts dans ce guide. En cas de blocage, docs/troubleshooting.md à la racine du repo couvre les pièges fréquents (rate-limit SSH, clé absente, collection manquante).

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn