
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.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- 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.
Architecture — où vit un plugin
Section intitulée « Architecture — où vit un plugin »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.pyQuand vous tapez ansible-inventory -i mon_fichier.yml --list, Ansible :
- Détecte que
mon_fichier.ymlcontientplugin: <nom>au top → c’est une config plugin. - Trouve le fichier Python correspondant dans les collections installées.
- Exécute le plugin avec la config YAML en input.
- 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.
Activer un plugin dans ansible.cfg
Section intitulée « Activer un plugin dans ansible.cfg »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_inventoryPlugins built-in (toujours actifs si listés) :
| Plugin | Rôle |
|---|---|
host_list | Hôtes en CLI : -i 'host1,host2,' |
script | Scripts d’inventaire (executables retournant JSON) |
auto | Détection automatique du format |
yaml | Inventaire statique YAML |
ini | Inventaire statique INI |
toml | Inventaire 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.
Format de retour — le JSON Ansible
Section intitulée « Format de retour — le JSON Ansible »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 (équivalenthost_vars/<host>.yml).<groupe>.hosts: liste des hôtes du groupe.<groupe>.children: sous-groupes (équivalent:childrenen INI).<groupe>.vars: variables du groupe (équivalentgroup_vars/<groupe>.yml).
C’est le format que retourne ansible-inventory --list. Quand vous écrivez un script custom, vous reproduisez exactement ce format.
Voir ce qu’un plugin retourne
Section intitulée « Voir ce qu’un plugin retourne »ansible-inventory -i inventory/libvirt.yml --listAffiche 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:oukeyed_groups:qui ne marche pas.
ansible-inventory -i inventory/libvirt.yml --graphVue arborescente plus lisible, mais sans détail des variables.
Configuration commune des plugins
Section intitulée « Configuration commune des plugins »Tous les plugins de collection partagent un socle d’options communes :
plugin: community.libvirt.libvirturi: qemu:///system
# Cache (optionnel mais recommandé)cache: truecache_plugin: jsonfilecache_timeout: 3600cache_connection: /tmp/ansible_inventory_cache
# Création de groupes (Jinja conditionnel)groups: webservers: inventory_hostname.startswith('web')
# Création de groupes par valeur de variablekeyed_groups: - prefix: state key: state
# Calcul de variables à partir d'autres variablescompose: ansible_host: private_ip | default(public_ip)| Option | Effet |
|---|---|
cache: true | Cache 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 |
Le cache — éviter de marteler l’API
Section intitulée « Le cache — éviter de marteler l’API »Sans cache, chaque commande Ansible retape l’API du plugin :
ansible-inventory --list # → API callansible-inventory --graph # → API callansible all -m ping # → API callSur un compte AWS avec 200 instances, c’est 3 × ~5 secondes = 15s de latence inutile. Avec le cache :
cache: truecache_plugin: jsonfilecache_timeout: 3600 # 1 heurecache_connection: /tmp/ansible_inv_cachePremiè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 :
rm /tmp/ansible_inv_cache/*# ouansible-inventory --list --refresh-cacheDebug avec -vvv
Section intitulée « Debug avec -vvv »Quand un plugin ne retourne rien d’attendu :
ansible-inventory -i inventory/libvirt.yml --list -vvv 2>&1 | tail -30Affiche :
- 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.
Plugins built-in — le script plugin
Section intitulée « Plugins built-in — le script plugin »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 :
chmod +x inventory/mon_script.pyansible-inventory -i inventory/mon_script.py --listAucune 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.
Combiner statique et dynamique
Section intitulée « Combiner statique et dynamique »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éesansible-inventory -i inventory/ --listAnsible lit les deux et fusionne. Pratique pour compléter un plugin (ex : libvirt fournit les noms, le YAML statique fournit les IPs).
Sécurité — le piège du plugin custom
Section intitulée « Sécurité — le piège du plugin custom »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 0750maximum (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.
Pièges courants
Section intitulée « Pièges courants »| Symptôme | Cause | Fix |
|---|---|---|
plugin not enabled warning | Plugin pas listé dans enable_plugins | Ajouter au ansible.cfg |
| Inventaire vide | Filtre trop restrictif ou auth manquant | --list -vvv pour voir le détail |
| Lent à chaque commande | Pas de cache configuré | cache: true + cache_plugin: jsonfile |
| Modification non visible | Cache pas expiré | --refresh-cache ou rm du cache |
groups: ne crée pas le groupe | Variable de filtre absente lors de l’évaluation | Utiliser keyed_groups: ou conditionnel sur inventory_hostname |
| Plugin trouvé mais erreur Python | Bindings manquants | Vérifier la doc du plugin (ansible-doc -t inventory ...) |
À retenir
Section intitulée « À retenir »- Un plugin d’inventaire est un fichier Python dans une collection — le fichier YAML que vous écrivez le configure.
enable_pluginsdansansible.cfgest mandatory pour activer un plugin.- Format de retour standard :
_meta.hostvars+ groupes avechosts:,children:,vars:. - Cache mandatory en prod :
cache: true+cache_timeout. -vvvpour 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.