Aller au contenu
Infrastructure as Code medium

Concepts des plugins d'inventaire Ansible : architecture et activation

10 min de lecture

Logo Ansible

Avant de plonger dans un plugin spécifique (libvirt, AWS, Proxmox), comprendre l’architecture d’un plugin d’inventaire vous évite des heures de debug. Un plugin est un programme Python qui implémente une interface standard : Ansible l’appelle, le plugin retourne du JSON qui décrit l’inventaire, et Ansible l’utilise comme s’il provenait d’un fichier statique.

Cette page couvre le fonctionnement interne, l’activation dans ansible.cfg, le format de retour attendu, et les règles de cache qui peuvent vous piéger.

  • L’architecture d’un plugin : où il vit, comment Ansible l’invoque.
  • Activer un plugin dans ansible.cfg (enable_plugins).
  • Comprendre le format JSON retourné (équivalent ansible-inventory --list).
  • Configurer le cache pour éviter de marteler une API à chaque commande.
  • Debugger un plugin qui ne retourne rien avec -vvv.

Un plugin d’inventaire est un fichier Python distribué dans une collection Ansible :

~/.ansible/collections/ansible_collections/
├── community/
│ ├── libvirt/
│ │ └── plugins/
│ │ └── inventory/
│ │ └── libvirt.py ← le plugin
│ └── general/
│ └── plugins/
│ └── inventory/
│ └── proxmox.py
└── amazon/
└── aws/
└── plugins/
└── inventory/
└── aws_ec2.py

Quand vous tapez ansible-inventory -i mon_fichier.yml --list, Ansible :

  1. Détecte que mon_fichier.yml contient plugin: <nom> au top → c’est une config plugin.
  2. Trouve le fichier Python correspondant dans les collections installées.
  3. Exécute le plugin avec la config YAML en input.
  4. Récupère la sortie JSON et l’utilise comme inventaire.

Vous n’écrivez pas le plugin (sauf script custom — voir page dédiée). Vous écrivez juste un fichier de config YAML qui dit au plugin quoi interroger et comment grouper.

Tous les plugins ne sont pas activés par défaut — pour des raisons de sécurité (un plugin malveillant ne peut pas tourner si non listé). Activation explicite dans ansible.cfg :

[inventory]
enable_plugins = host_list, script, auto, yaml, ini, toml, community.libvirt.libvirt, community.general.proxmox, amazon.aws.aws_ec2, netbox.netbox.nb_inventory

Plugins built-in (toujours actifs si listés) :

PluginRôle
host_listHôtes en CLI : -i 'host1,host2,'
scriptScripts d’inventaire (executables retournant JSON)
autoDétection automatique du format
yamlInventaire statique YAML
iniInventaire statique INI
tomlInventaire statique TOML (rare)

Plugins de collection : référencer en FQCN (community.libvirt.libvirt).

Sans cette activation, Ansible affiche un warning : Failed to parse inventory with 'auto' plugin: plugin not enabled.

Tous les plugins retournent le même format JSON standard :

{
"_meta": {
"hostvars": {
"web1.lab": {
"ansible_host": "10.10.20.21",
"tag_Environment": "prod",
"instance_id": "i-1234abcd"
},
"web2.lab": { ... }
}
},
"all": {
"children": ["webservers", "dbservers", "ungrouped"]
},
"webservers": {
"hosts": ["web1.lab", "web2.lab"],
"vars": {
"http_port": 8080
}
},
"dbservers": {
"hosts": ["db1.lab"]
}
}

Trois sections :

  • _meta.hostvars : variables par host (équivalent host_vars/<host>.yml).
  • <groupe>.hosts : liste des hôtes du groupe.
  • <groupe>.children : sous-groupes (équivalent :children en INI).
  • <groupe>.vars : variables du groupe (équivalent group_vars/<groupe>.yml).

C’est le format que retourne ansible-inventory --list. Quand vous écrivez un script custom, vous reproduisez exactement ce format.

Fenêtre de terminal
ansible-inventory -i inventory/libvirt.yml --list

Affiche le JSON complet du plugin. Utile pour :

  • Vérifier que le plugin trouve bien les hôtes attendus.
  • Inspecter les variables retournées (chaque plugin retourne ses propres facts).
  • Debugger un filtre groups: ou keyed_groups: qui ne marche pas.
Fenêtre de terminal
ansible-inventory -i inventory/libvirt.yml --graph

Vue arborescente plus lisible, mais sans détail des variables.

Tous les plugins de collection partagent un socle d’options communes :

plugin: community.libvirt.libvirt
uri: qemu:///system
# Cache (optionnel mais recommandé)
cache: true
cache_plugin: jsonfile
cache_timeout: 3600
cache_connection: /tmp/ansible_inventory_cache
# Création de groupes (Jinja conditionnel)
groups:
webservers: inventory_hostname.startswith('web')
# Création de groupes par valeur de variable
keyed_groups:
- prefix: state
key: state
# Calcul de variables à partir d'autres variables
compose:
ansible_host: private_ip | default(public_ip)
OptionEffet
cache: trueCache le résultat pour éviter de marteler l’API
groups:Crée des groupes selon des conditions Jinja (un par groupe)
keyed_groups:Crée un groupe par valeur d’une variable (ex: un groupe par tag AWS)
compose:Calcule de nouvelles variables à partir des facts retournés

Sans cache, chaque commande Ansible retape l’API du plugin :

Fenêtre de terminal
ansible-inventory --list # → API call
ansible-inventory --graph # → API call
ansible all -m ping # → API call

Sur un compte AWS avec 200 instances, c’est 3 × ~5 secondes = 15s de latence inutile. Avec le cache :

cache: true
cache_plugin: jsonfile
cache_timeout: 3600 # 1 heure
cache_connection: /tmp/ansible_inv_cache

Première commande : appel API, résultat sauvé en JSON. Commandes suivantes (dans l’heure) : lecture du cache local, instantané.

Limite : si vous créez une nouvelle VM, elle n’apparaît pas tant que le cache n’a pas expiré. Pour rafraîchir manuellement :

Fenêtre de terminal
rm /tmp/ansible_inv_cache/*
# ou
ansible-inventory --list --refresh-cache

Quand un plugin ne retourne rien d’attendu :

Fenêtre de terminal
ansible-inventory -i inventory/libvirt.yml --list -vvv 2>&1 | tail -30

Affiche :

  • L’appel API que le plugin fait.
  • Les éventuelles erreurs (auth, réseau, parsing).
  • Les hôtes trouvés avant filtrage.
  • Le cache hit/miss.

C’est le premier réflexe de debug. Sans -vvv, vous voyez juste un inventaire vide sans savoir pourquoi.

Le plugin script est un cas particulier : il accepte n’importe quel fichier exécutable comme source d’inventaire. Le fichier doit retourner du JSON Ansible quand il est appelé avec --list :

Fenêtre de terminal
chmod +x inventory/mon_script.py
ansible-inventory -i inventory/mon_script.py --list

Aucune config YAML, aucune collection requise — le plugin script (built-in) interprète le résultat. C’est le fallback universel quand aucun plugin officiel n’existe — voir Écrire un script custom.

Les plugins coexistent avec le statique. Un dossier d’inventaire peut contenir :

inventory/
├── 01-libvirt.yml ← plugin
├── 02-static.yml ← inventaire statique YAML
└── group_vars/
└── all.yml ← variables partagées
Fenêtre de terminal
ansible-inventory -i inventory/ --list

Ansible lit les deux et fusionne. Pratique pour compléter un plugin (ex : libvirt fournit les noms, le YAML statique fournit les IPs).

Le plugin script exécute n’importe quel binaire. Risque : un script malveillant déposé dans inventory/ exécute du code arbitraire avec les droits de l’utilisateur Ansible.

Garde-fous :

  • Les scripts d’inventaire doivent être en mode 0750 maximum (pas world-writable).
  • Code review obligatoire avant d’ajouter un script.
  • En CI : utiliser un runner avec scope minimal.
  • Préférer un plugin officiel signé (Galaxy/Automation Hub) à un script maison quand c’est possible.
SymptômeCauseFix
plugin not enabled warningPlugin pas listé dans enable_pluginsAjouter au ansible.cfg
Inventaire videFiltre trop restrictif ou auth manquant--list -vvv pour voir le détail
Lent à chaque commandePas de cache configurécache: true + cache_plugin: jsonfile
Modification non visibleCache pas expiré--refresh-cache ou rm du cache
groups: ne crée pas le groupeVariable de filtre absente lors de l’évaluationUtiliser keyed_groups: ou conditionnel sur inventory_hostname
Plugin trouvé mais erreur PythonBindings manquantsVérifier la doc du plugin (ansible-doc -t inventory ...)
  • Un plugin d’inventaire est un fichier Python dans une collection — le fichier YAML que vous écrivez le configure.
  • enable_plugins dans ansible.cfg est mandatory pour activer un plugin.
  • Format de retour standard : _meta.hostvars + groupes avec hosts:, children:, vars:.
  • Cache mandatory en prod : cache: true + cache_timeout.
  • -vvv pour debugger ce qu’un plugin retourne.
  • Statique + dynamique se combinent dans un dossier d’inventaire.
  • Plugin script = fallback universel ; vérifier les permissions et faire la code review.

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