
NetBox est la référence open-source en IPAM/DCIM : il gère vos racks, vos devices physiques, vos VMs, vos VLANs, vos prefixes IP. Si NetBox est déjà déployé chez vous, il est la source de vérité naturelle pour Ansible, pas la peine de dupliquer l'inventaire ailleurs.
Le plugin netbox.netbox.nb_inventory transforme votre instance NetBox en inventaire Ansible dynamique avec des filtres très fins (par site, par role, par status, par tag, par tenant). C'est le pattern recommandé dans les moyennes/grandes entreprises qui ont déjà investi dans NetBox.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Configurer le plugin avec un token API NetBox.
- Filtrer les hôtes par site, role, status, tag NetBox.
- Grouper automatiquement par les attributs NetBox.
- Récupérer les IPs depuis l'IPAM NetBox.
- Combiner devices physiques et virtualization dans un même inventaire.
Prérequis
Section intitulée « Prérequis »- Une instance NetBox 3.x ou 4.x opérationnelle.
- Token API NetBox créé.
- Collection
netbox.netboxinstallée. pynetboxPython :pip install pynetbox.
Création d'un token NetBox
Section intitulée « Création d'un token NetBox »Sur l'UI NetBox : User → API Tokens → Add a token. Trois réglages de ce formulaire séparent un token correct d'un token à risque, et ce sont les trois que l'on laisse le plus souvent aux valeurs par défaut. Write enabled est coché par défaut alors qu'un inventaire n'écrit jamais dans NetBox. Allowed IPs est vide par défaut, ce qui rend le token utilisable depuis n'importe où. Et Expires vide crée un token éternel, donc impossible à faire tourner sans casser quelque chose un jour.
| Champ | Valeur recommandée |
|---|---|
| User | ansible-readonly (créer ce user au préalable) |
| Description | Inventaire dynamique Ansible |
| Write enabled | ❌ Décocher (lecture seule) |
| Allowed IPs | IP du control node Ansible (restriction réseau) |
| Expires | Date d'expiration (ex: 1 an) |
Copier le token généré, il sera utilisé une seule fois (mais peut être recréé).
Installation
Section intitulée « Installation »Deux composants sont nécessaires et ils s'installent par des canaux
différents. La collection netbox.netbox apporte le plugin d'inventaire,
elle vient de Galaxy. La bibliothèque pynetbox est une dépendance Python
du côté des modules de la collection ; elle s'installe avec pip, dans
l'environnement Python qui exécute Ansible. Épinglez les deux versions, sinon
un ansible-galaxy lancé six mois plus tard ramènera une collection dont le
comportement de regroupement peut avoir changé.
ansible-galaxy collection install netbox.netbox:==3.23.0pip install 'pynetbox==7.8.0'Activer dans ansible.cfg :
[inventory]enable_plugins = host_list, script, auto, yaml, ini, netbox.netbox.nb_inventoryConfiguration minimale
Section intitulée « Configuration minimale »Le fichier d'inventaire d'un plugin dynamique n'est pas une liste d'hôtes,
c'est une configuration de source. Son nom doit se terminer par .yml ou
.yaml et sa première clé doit être plugin:, sinon le plugin auto ne
reconnaît pas le fichier et Ansible le traite comme un inventaire YAML
classique, donc vide. Le champ validate_certs: true est le défaut, gardez-le
explicite : c'est la ligne qu'on est tenté de passer à false le jour d'un
certificat auto-signé, et le rendre visible force à en faire un choix conscient.
Créer inventory/netbox.yml :
---plugin: netbox.netbox.nb_inventoryapi_endpoint: https://netbox.example.comtoken: !vault | $ANSIBLE_VAULT;1.1;AES256 3736...validate_certs: trueLe token chiffré avec Ansible Vault :
ansible-vault encrypt_string '<le-token>' --name tokenTester :
ansible-inventory -i inventory/netbox.yml --graphSortie : tous vos devices NetBox apparaissent comme des hôtes Ansible.
Filtrer par status, role, site
Section intitulée « Filtrer par status, role, site »Sans filtre, le plugin retourne toutes les machines de NetBox. Pour ne garder que certaines :
plugin: netbox.netbox.nb_inventoryapi_endpoint: https://netbox.example.comtoken: !vault | ...
# Filtres NetBox (équivalent des filtres URL de l'API REST)query_filters: - status: active - role: webserver - tag: managed-by-ansibleAvantage : la liste retournée par NetBox est déjà filtrée côté API, moins de payload, plus rapide.
# Multi-sitequery_filters: - status: active - site: parisGrouper par attributs NetBox
Section intitulée « Grouper par attributs NetBox »NetBox a déjà ses propres attributs structurés (site, role, manufacturer, status). Le plugin les expose automatiquement :
plugin: netbox.netbox.nb_inventoryapi_endpoint: https://netbox.example.comtoken: !vault | ...
group_by: - device_roles # groupe par role: webserver, dbserver, switch - sites # groupe par site: paris, londres - device_types # groupe par modèle: dell-r740, hp-dl380 - tags # groupe par tag NetBox - status # groupe par status: active, planned, decommissioning - region # groupe par région (toujours au singulier) - tenants # groupe par tenant (multi-tenant NetBox)Attention à la forme des clés : l'option plurals vaut true par défaut, ce
qui impose les formes plurielles sites, tenants, tags,
device_roles, device_types, manufacturers, platforms, racks. Quatre
clés font exception et restent au singulier quelle que soit la valeur de
plurals : region, status, location, site_group. Écrire regions
fait échouer la lecture de l'inventaire avec une erreur de valeur non
autorisée. Les noms de groupes sont construits à partir du slug NetBox, pas
du nom d'affichage : un site nommé « Paris DC1 » de slug paris-dc1 donne le
groupe sites_paris-dc1.
Résultat :
@all: |--@device_roles_webserver: | |--web1.paris.example.com | |--web2.paris.example.com |--@device_roles_dbserver: | |--db1.paris.example.com |--@sites_paris: | |--web1.paris.example.com | |--db1.paris.example.com |--@status_active: | |--... (toutes les machines actives)Vous pouvez maintenant cibler device_roles_webserver:&sites_paris pour les webservers du site Paris uniquement.
Inclure les VMs (virtualization)
Section intitulée « Inclure les VMs (virtualization) »NetBox distingue les devices physiques (/api/dcim/devices/) des VMs
(/api/virtualization/virtual-machines/). Le plugin interroge les deux
points d'accès systématiquement : il n'existe aucune option pour activer les
VMs, elles sont là par défaut. Ce que vous pouvez régler, c'est la façon de les
distinguer et le volume de données rapatriées.
plugin: netbox.netbox.nb_inventoryapi_endpoint: https://netbox.example.comtoken: !vault | ...
config_context: false # ne pas charger les config_contexts (alourdit)group_by: - is_virtual # crée un groupe is_virtual contenant les seules VMs - status
# Filtres distincts pour les devices et pour les VMsdevice_query_filters: - has_primary_ip: 'true'vm_query_filters: - status: activeLe groupe is_virtual ne contient que les machines virtuelles, le plugin ne
crée volontairement pas le groupe inverse. Pour ne viser que le matériel
physique, ciblez donc all:!is_virtual. Pour ne filtrer que d'un côté, utilisez device_query_filters:
et vm_query_filters: plutôt que query_filters:, qui s'applique aux deux
requêtes à la fois. Un piège classique en découle : un query_filters: avec
role: webserver retourne zéro VM si vos VMs ne portent pas de rôle NetBox.
Récupérer les IPs
Section intitulée « Récupérer les IPs »NetBox stocke une IP primaire sur chaque device et chaque VM. Le plugin la
lit et alimente ansible_host automatiquement, sans configuration, en
retirant lui-même le masque : un primary_ip NetBox à 10.20.0.14/24 donne
ansible_host: 10.20.0.14. Rien à composer pour le cas courant.
Deux options changent ce comportement quand votre parc ne s'adresse pas par
IP. ansible_host_dns_name: true fait pointer ansible_host sur le champ
DNS Name de l'IP primaire. oob_ip_as_primary_ip: true utilise l'adresse
out-of-band, ce qui correspond au cas des équipements réseau que l'on
administre par leur interface de management.
plugin: netbox.netbox.nb_inventoryapi_endpoint: https://netbox.example.comtoken: !vault | ...
ansible_host_dns_name: false # laisser ansible_host sur l'IP primaireoob_ip_as_primary_ip: false # passer à true pour les équipements réseau
compose: ansible_user: "'admin' if 'switch' in tags else 'ansible'"compose: calcule des variables Ansible à partir des données déjà
présentes dans les host vars. L'exemple ci-dessus choisit le compte SSH selon
la présence d'un tag ; il fonctionne parce que le host var tags est une
liste de slugs, donc directement testable avec in.
Variables exposées par le plugin
Section intitulée « Variables exposées par le plugin »Le plugin ne recopie pas les objets NetBox tels quels, il les aplatit en
host vars. Deux règles gouvernent les noms et il faut les connaître avant
d'écrire un template. D'abord, l'option plurals valant true par défaut, la
plupart des attributs de relation arrivent sous forme de liste à un seul
élément : sites, device_roles, device_types, manufacturers,
platforms, tenants. On y accède donc par [0]. Ensuite, la valeur stockée
est le slug NetBox, pas le nom d'affichage.
Trois host vars échappent à cette règle : status reste un dictionnaire
(value et label), tags est une liste de slugs de longueur variable, et
primary_ip4 / primary_ip6 sont des chaînes d'adresse sans masque.
- name: Afficher les attributs NetBox de l'hôte ansible.builtin.debug: msg: | Device {{ inventory_hostname }} : - Site : {{ sites[0] }} - Role : {{ device_roles[0] }} - Manufacturer : {{ manufacturers[0] }} - Model : {{ device_types[0] }} - Serial : {{ serial }} - Status : {{ status.label }} - Primary IP : {{ primary_ip4 }} - Tags : {{ tags | join(', ') }}Pour obtenir la structure NetBox complète du site au lieu de son seul slug,
activez site_data: true ; sites[0] devient alors le dictionnaire renvoyé
par l'API et sites[0].name redevient valide. C'est ce qui rend NetBox utile
ici : vos playbooks lisent la donnée IPAM/DCIM sans la dupliquer
ailleurs.
Cache, mandatory
Section intitulée « Cache, mandatory »NetBox peut être lent sur de gros parcs (300+ devices). Cache obligatoire :
plugin: netbox.netbox.nb_inventoryapi_endpoint: https://netbox.example.comtoken: !vault | ...
cache: truecache_plugin: jsonfilecache_timeout: 600cache_connection: /tmp/ansible_netbox_cachePour rafraîchir après modification dans NetBox :
ansible-inventory -i inventory/netbox.yml --list --refresh-cachePatterns courants
Section intitulée « Patterns courants »Patcher tous les serveurs RHEL d'un site
Section intitulée « Patcher tous les serveurs RHEL d'un site »L'intersection :& de deux groupes générés par NetBox remplace la liste de
machines qu'on maintenait à la main. Le tiret dans dell-r740 vient du slug
NetBox : Ansible accepte ce caractère dans un nom de groupe mais émet un
avertissement, réglé par TRANSFORM_INVALID_GROUP_CHARS. Vérifiez toujours la
cible avec --list-hosts avant de lancer le playbook pour de bon.
ansible-playbook -i inventory/netbox.yml \ --limit 'sites_paris:&device_types_dell-r740' \ patch-rhel.ymlConfigurer uniquement les machines en statut "planned"
Section intitulée « Configurer uniquement les machines en statut "planned" »ansible-playbook -i inventory/netbox.yml \ --limit 'status_planned' \ bootstrap.ymlNetBox suit le cycle de vie : planned → active → decommissioning → decommissioned. Cibler les planned permet de bootstrap uniquement les nouvelles machines.
Audit complet à partir des tags
Section intitulée « Audit complet à partir des tags »ansible-playbook -i inventory/netbox.yml \ --limit 'tags_pci-dss' \ audit-pci.ymlToutes les machines taggées pci-dss dans NetBox sont auditées. Aucune liste à maintenir, la source de vérité est NetBox.
Pièges courants
Section intitulée « Pièges courants »La moitié de ces symptômes se diagnostique avec la même commande,
ansible-inventory -i inventory/netbox.yml --list -vvv, qui affiche les URL
réellement appelées et le code HTTP de chaque réponse. Commencez par là plutôt
que par modifier la configuration au hasard : un inventaire vide sans erreur
vient presque toujours d'un query_filters trop strict, pas d'un problème de
plugin.
| Symptôme | Cause | Fix |
|---|---|---|
pynetbox not found | Module Python manquant | pip install 'pynetbox==7.8.0' |
401 Unauthorized | Token expiré ou mal écrit | Recréer le token, vérifier les permissions |
| Inventaire vide sans erreur | query_filters trop strict, ou slug inexistant | Tester le filtre sur l'API REST NetBox |
| Requêtes très nombreuses | fetch_all: true (défaut) sur un parc filtré | fetch_all: false groupe les requêtes par lots |
HTTP 414 URI Too Long | fetch_all: false sur beaucoup d'hôtes | Baisser max_uri_length (défaut 4000) |
| Lent (>10s) | Pas de cache | cache: true mandatory |
Allowed IPs bloque | Token configuré avec IP allowed | Ajouter l'IP du control node |
value of group_by must be one of... | Clé inexistante, par exemple regions | Utiliser region, toujours au singulier |
group_by option "site" is not valid | Clé au singulier alors que plurals vaut true | Écrire sites, ou passer plurals: false |
Quand préférer NetBox
Section intitulée « Quand préférer NetBox »La question n'est pas « NetBox est-il un bon inventaire », mais « avez-vous déjà NetBox et le tenez-vous à jour ». Un NetBox alimenté à la main et jamais relu produit un inventaire faux, et un inventaire faux est pire qu'un fichier statique qu'on sait incomplet. Lisez donc la première ligne du tableau comme une condition d'entrée, pas comme un critère parmi d'autres.
| Critère | NetBox recommandé | Autre solution |
|---|---|---|
| Source de vérité IPAM/DCIM existante | ✅ | Sans objet |
| Petit parc (< 50 hôtes) | Surdimensionné | Statique YAML |
| Cloud public (AWS/Azure/GCP) | Plugin cloud direct | NetBox redondant |
| Mix on-prem + cloud | Possible (NetBox sync) | Plusieurs -i |
| Audit conformité (tags, owners) | ✅ excellence | Galère sans NetBox |
À retenir
Section intitulée « À retenir »- NetBox = source de vérité IPAM/DCIM unifiée, pas de duplication d'inventaire.
netbox.netbox.nb_inventory= plugin officiel maintenu par NetBox Labs.- Token chiffré Vault + restriction
Allowed IPsau token. query_filters:= filtrer côté API (status, role, site, tag).group_by:= grouper par attributs NetBox natifs.ansible_hostest déjà rempli par le plugin depuis l'IP primaire,compose:sert aux variables restantes (ansible_user, etc.).plurals: truepar défaut : les host vars de relation sont des listes à un élément, accès en[0].- Cache mandatory dès qu'on dépasse quelques centaines de devices.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Modules Ansible, vue d'ensemble : le concept de module, les FQCN et les collections, socle de tous vos playbooks.
- Trouver le bon module :
netbox.netboxest une collection tierce, cette page donne la méthode et les garde-fous avant d'en installer une.