
Les plugins d’inventaire sont géniaux pour gérer un parc évolutif, mais ils s’exécutent avant le playbook. Que faire quand un play provisionne une VM dont on ne connaît pas encore le nom ou l’IP, et que le play suivant doit l’utiliser ? add_host ajoute un hôte au runtime, group_by crée des groupes basés sur les facts, et meta: refresh_inventory recharge les plugins en cours de play.
Ces trois mécanismes complètent les plugins d’inventaire — ils sont indispensables pour orchestrer du provisioning + configuration en un seul playbook.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Ajouter un hôte à l’inventaire au runtime avec
add_host. - Créer des groupes dynamiques basés sur les facts avec
group_by. - Forcer le rechargement d’un plugin d’inventaire avec
meta: refresh_inventory. - Combiner ces 3 mécanismes pour un workflow provision + configure en un seul playbook.
- Persister un inventaire dynamique entre plays (limites et workarounds).
Prérequis
Section intitulée « Prérequis »- Avoir lu Concepts des plugins d’inventaire.
- Comprendre la notion de plays multiples dans un même playbook.
Le module ansible.builtin.add_host
Section intitulée « Le module ansible.builtin.add_host »add_host ajoute un hôte à l’inventaire en mémoire pendant l’exécution. L’hôte devient utilisable par les plays suivants du même playbook.
Cas d’usage typique — provisioning cloud
Section intitulée « Cas d’usage typique — provisioning cloud »---- name: Provisionner une VM AWS hosts: localhost gather_facts: false tasks: - name: Lancer une instance EC2 amazon.aws.ec2_instance: name: web-new-2026 instance_type: t3.micro image_id: ami-0abcdef1234567890 wait: true register: ec2_result
- name: Ajouter la nouvelle instance à l'inventaire ansible.builtin.add_host: name: "{{ ec2_result.instances[0].public_ip_address }}" groups: webservers,new_instances ansible_user: ec2-user ansible_ssh_private_key_file: ~/.ssh/aws-key
- name: Configurer la nouvelle VM hosts: new_instances tasks: - name: Installer nginx ansible.builtin.dnf: name: nginx state: presentLe pattern : le premier play tourne sur localhost, provisionne la VM, récupère son IP, l’ajoute via add_host. Le second play cible le groupe new_instances qui vient d’être créé. Sans add_host, il faudrait deux playbooks séparés + un mécanisme de transmission de l’IP.
Paramètres clés
Section intitulée « Paramètres clés »| Paramètre | Effet |
|---|---|
name: | Hostname ou IP de l’hôte à ajouter |
groups: | Groupes auxquels l’ajouter (séparés par virgule) |
ansible_host: | IP de connexion si différente du name: |
ansible_user: | User SSH pour cette VM |
<var>: <valeur> | Toute autre variable est attachée au host |
- Volatil : l’hôte n’existe que pour ce run. Le run suivant ne le voit pas.
- Pas de
host_vars/: les variables sont définies inline dans leadd_host:. - Pas dans
--graphentre deux runs : mêmeansible-inventory --graphne le voit pas (il n’a pas exécuté le play).
Pour persister, il faut écrire l’hôte dans un fichier d’inventaire via template: ou lineinfile:.
Le module ansible.builtin.group_by
Section intitulée « Le module ansible.builtin.group_by »group_by crée un groupe à la volée basé sur les facts ou variables des hôtes. Idéal pour cibler par caractéristique runtime plutôt que par config statique.
Cas d’usage typique — déploiement par OS
Section intitulée « Cas d’usage typique — déploiement par OS »---- name: Grouper par famille d'OS hosts: all tasks: - name: Créer un groupe par OS family ansible.builtin.group_by: key: "os_{{ ansible_facts.os_family | lower }}"
- name: Tâches spécifiques RHEL hosts: os_redhat tasks: - name: Installer firewalld ansible.builtin.dnf: name: firewalld state: present
- name: Tâches spécifiques Debian hosts: os_debian tasks: - name: Installer ufw ansible.builtin.apt: name: ufw state: presentLe pattern : le premier play gather_facts sur tous les hôtes et crée des groupes os_redhat, os_debian, os_archlinux selon ansible_os_family. Les plays suivants ciblent ces groupes générés au runtime.
Avantage sur when: ansible_os_family == 'RedHat' : code plus propre quand vous avez beaucoup de tâches par OS.
Autres exemples
Section intitulée « Autres exemples »# Grouper par nombre de CPU- ansible.builtin.group_by: key: "cpu_{{ ansible_facts.processor_cores }}"
# Grouper par version de distribution- ansible.builtin.group_by: key: "rhel_{{ ansible_facts.distribution_major_version }}"
# Grouper par disponibilité d'un service (custom fact)- ansible.builtin.group_by: key: "has_docker" when: ansible_facts.services['docker.service'] is defined- Comme
add_host, volatil — n’existe que pour le run. - Les groupes créés par
group_byne sont vus que par les plays suivants, pas par le play courant.
meta: refresh_inventory
Section intitulée « meta: refresh_inventory »Quand un plugin d’inventaire dynamique a un cache, meta: refresh_inventory force le rafraîchissement entre deux plays.
Cas d’usage — provision via Terraform
Section intitulée « Cas d’usage — provision via Terraform »---- name: Provisionner avec Terraform hosts: localhost tasks: - name: Lancer terraform apply ansible.builtin.command: terraform apply -auto-approve args: chdir: ./terraform/
- name: Rafraîchir l'inventaire pour voir les nouvelles VMs ansible.builtin.meta: refresh_inventory
- name: Configurer les nouvelles VMs hosts: webservers # ce groupe contient maintenant les VMs Terraform tasks: - name: Installer nginx ansible.builtin.dnf: name: nginx state: presentSans refresh_inventory, le second play utilise le cache de l’inventaire dynamique — qui ne contient pas encore les nouvelles VMs Terraform.
Quand l’utiliser
Section intitulée « Quand l’utiliser »- Après une commande qui modifie l’infrastructure (Terraform, virt-install, AWS CLI).
- Avant un play qui doit voir les nouvelles ressources.
- Sur un plugin avec
cache: trueconfiguré (sinon pas nécessaire).
Combinaison des 3 — workflow complet
Section intitulée « Combinaison des 3 — workflow complet »Provisioning AWS + bootstrap Linux + déploiement application en un seul playbook :
---- name: 1. Provisionner l'infra hosts: localhost gather_facts: false tasks: - name: Lancer Terraform ansible.builtin.command: terraform apply -auto-approve args: chdir: ./terraform/
- name: Récupérer les IPs ansible.builtin.command: terraform output -json instance_ips register: ips_output changed_when: false
- name: Ajouter les nouvelles VMs à l'inventaire ansible.builtin.add_host: name: "{{ item }}" groups: new_vms ansible_user: ec2-user loop: "{{ ips_output.stdout | from_json }}"
- name: 2. Bootstrap Linux (gather_facts pour obtenir l'OS) hosts: new_vms tasks: - name: Mettre à jour les paquets ansible.builtin.dnf: name: "*" state: latest
- name: Grouper par OS family pour la suite ansible.builtin.group_by: key: "os_{{ ansible_facts.os_family | lower }}"
- name: 3. Configuration RHEL hosts: os_redhat tasks: - name: Installer firewalld ansible.builtin.dnf: name: firewalld state: present
- name: 4. Configuration Debian hosts: os_debian tasks: - name: Installer ufw ansible.builtin.apt: name: ufw state: presentQuatre plays, un seul fichier. Sans ces modules, il faudrait des scripts shell intermédiaires + plusieurs invocations d’Ansible.
Persister un inventaire dynamique
Section intitulée « Persister un inventaire dynamique »Les modules add_host et group_by sont volatils. Pour persister un host découvert au runtime, écrire l’inventaire :
- name: Persister la liste des nouvelles VMs ansible.builtin.template: src: inventory.j2 dest: ./inventory/runtime-discovered.yml mode: "0644" delegate_to: localhost vars: discovered_hosts: "{{ groups['new_vms'] }}"Avec inventory.j2 :
---all: children: discovered: hosts: {% for h in discovered_hosts %} {{ h }}: ansible_host: {{ hostvars[h]['ansible_host'] | default(h) }} {% endfor %}Le fichier généré est utilisable par les commandes Ansible futures : ansible-playbook -i ./inventory/runtime-discovered.yml ....
Comparaison — quand utiliser quoi ?
Section intitulée « Comparaison — quand utiliser quoi ? »| Besoin | Outil |
|---|---|
| Inventaire stable connu d’avance | Statique YAML (inventory/hosts.yml) |
| Source externe (cloud, NetBox, libvirt) | Plugin d’inventaire (libvirt, AWS, Proxmox) |
| Ajouter un hôte juste-en-temps dans un play | add_host: |
| Cibler par caractéristique runtime (OS, capacité) | group_by: |
| Voir des VMs créées par le play courant | meta: refresh_inventory |
| Persister une découverte runtime | template: + fichier d’inventaire |
Pièges courants
Section intitulée « Pièges courants »| Symptôme | Cause | Fix |
|---|---|---|
add_host exécuté mais hôte absent au play suivant | Plays définis dans des fichiers séparés | Mettre tous les plays dans le même playbook YAML |
group_by ne crée pas le groupe attendu | gather_facts désactivé | Activer gather_facts: true dans le play parent |
| Plugin dynamique ne voit pas la nouvelle VM | Cache du plugin | meta: refresh_inventory + --refresh-cache au besoin |
Variables passées à add_host ignorées | Réservé : ne pas overrider ansible_host avec mauvaise valeur | Vérifier ansible-inventory --host <new> après le play |
add_host plante en CI | Tentative d’exécuter sur un host déjà existant | add_host est idempotent, mais le groups: ajouté peut poser problème |
À retenir
Section intitulée « À retenir »add_host:= ajouter un hôte au runtime, utilisable par les plays suivants. Volatil.group_by:= créer un groupe basé sur les facts (ansible_os_family, etc.). Volatil.meta: refresh_inventory= forcer le rechargement d’un plugin avec cache. À placer entre deux plays.- Combinaison des 3 = workflow provision + configure en un seul playbook.
- Persister un inventaire runtime nécessite d’écrire un fichier YAML via
template:. - Plays séparés :
add_hostetgroup_byne sont visibles que dans les plays suivants du même playbook.