
Enter NetBox Ansible dynamic inventory: a seamless integration where NetBox’s REST API serves as the live source of truth, querying devices, sites, tags, platforms, and custom fields on every Ansible run.
Static Ansible inventory files in YAML or INI format work for small labs but fail miserably in production networks. Devices change or new switches deploy, IPs reassign, sites expand and your inventory drifts, causing playbook failures, misconfigurations, and audit nightmares.
What is NetBox Ansible dynamic inventory? It uses the official netbox.netbox.nb_inventory plugin (or pynetbox scripts) to generate JSON output dynamically. Ansible commands like ansible-inventory --list pull fresh data via filters:
sites=PR1, role=router, or tag=production. No manual edits, no stale host_vars and NetBox ensures accuracyWhy adopt it in 2026? Modern GitOps and CI/CD demand versioned, automated workflows. Dynamic inventories eliminate drift, scale to thousands of devices across multi-cloud/hybrid environments, and integrate with emerging AI-driven orchestration. As networks grow more complex with edge computing and zero-trust models, relying on NetBox prevents errors that static files can’t catch.
netbox.netbox.nb_inventory Plugin (Recommended 2025)The official NetBox collection plugin (netbox.netbox.nb_inventory) replaces all legacy scripts. It queries NetBox via REST on every Ansible run, guaranteeing a truly dynamic inventory that reflects real-time changes in devices, IPs, tags, and custom fields—no caching lag or manual sync required.
ansible-galaxy collection install netbox.netboxinventory/netbox.yml)---
plugin: netbox.netbox.nb_inventory
api_endpoint: https://netbox.example.com
token: your_netbox_api_token_here # ← put in vault in real life
validate_certs: true # ← change to true in prod!
query_filters:
- status: active
group_by:
- device_roles
- sites # ← confirmed: plural per plugin docs
- tags
host_vars:
ansible_host: primary_ip4__address
compose:
monitoring_level: >-
{% if 'critical' in tags %}critical{% else %}standard{% endif %}The netbox.netbox.nb_inventory plugin is the official Ansible inventory plugin maintained by the NetBox team. It queries NetBox in real time via its REST API, eliminating static host files and ensuring the Ansible dynamic inventory always reflects the current source-of-truth state.
api_endpoint points to your NetBox instance; the token is a NetBox API token with read access to Devices and IPAM. Combined with validate_certs: true, this guarantees secure, authenticated pulls for every Ansible run.
query_filters limit returned objects (e.g., status: active). This reduces API payload and prevents decommissioned or pre production devices from appearing in the live Ansible inventory, keeping execution scopes clean and intentional.
group_by uses NetBox attributes (device_roles, sites, tags) to create Ansible groups automatically. Using the plural sites matches the plugin’s internal mapping, producing predictable groups like sites_ams-01 or device_roles_router for targeted playbooks.
host_vars maps NetBox fields directly to Ansible facts. Setting ansible_host: primary_ip4__address ensures Ansible connects to the device’s management IP without manual host file maintenance.
The compose block builds derived variables using Jinja2. Here it inspects the device’s tags and sets monitoring_level dynamically, enabling role-based logic (e.g., stricter monitoring playbooks for critical-tagged devices) directly from NetBox data.
ansible-inventory -i inventory/netbox.yml --graphExample output:
@all:
|--@ams_01:
| |--router01.ams01
| |--switch02.ams01
|--@router:
| |--router01.ams01
|--@cisco_ios:
| |--router01.ams01The classic Python script from NetBox contrib remains popular in air-gapped or older environments. It outputs JSON inventory when called with –list or –host, but lacks native Ansible collection features like built-in caching, vault integration, and plural group_by keys, making it deprecated for new netbox ansible dynamic inventory deployments.
# Download latest from NetBox GitHub
wget https://github.com/netbox-community/netbox/blob/develop/contrib/netbox-dynamic-inventory.py
chmod +x netbox-dynamic-inventory.pyUsage:
./netbox-dynamic-inventory.py --list --url https://netbox.example.com --token YOUR_TOKENGrouping by custom fields (e.g., custom_field_environment) instantly creates Ansible groups such as environment_production or environment_staging. This turns NetBox into a policy engine: a single custom field change in NetBox automatically reshuffles hosts across playbooks without touching YAML.
group_by:
- custom_field_environmentCombining tags, sites, and device_roles in group_by generates deeply nested, predictable groups (e.g., sites_ams-01, device_roles_router, tags_backup-daily). This structure enables highly granular playbooks while keeping the netbox ansible dynamic inventory 100 % data-driven.
group_by:
- tags
- site
compose:
ansible_group_priority: "50 if 'critical' in tags else 10"Filters like primary_ip4__address: “!*172.16.*” exclude out-of-band management VLANs from the inventory. This prevents Ansible from attempting in-band connections to management-only IPs, a common pain point when building reliable netbox ansible dynamic inventory setups.
query_filters:
- primary_ip4__address: "!*172.16.*" # exclude mgmt VLANEnabling the jsonfile cache (cache: true, cache_timeout: 900) reduces NetBox API load during frequent runs (e.g., AWX/Tower polling). The inventory stays dynamic yet performant—Ansible refreshes only when the cache expires, balancing freshness with API efficiency.
cache: true
cache_plugin: jsonfile
cache_timeout: 900
cache_connection: /tmp/netbox_inventory_cachevalidate_certs: true in production# inventory/netbox.yml
plugin: netbox.netbox.nb_inventory
api_endpoint: https://netbox.yourdomain.com
token: "{{ vault_netbox_token }}"
validate_certs: true
query_filters:
- status: active
group_by:
- device_roles
- site
- tags
- custom_field_environment
host_vars:
ansible_host: primary_ip4__address
compose:
ansible_connection: network_cli
ansible_network_os: "{{ platform__napalm_driver | default('ios') }}"
monitoring_level: "'critical' if 'critical' in tags else 'standard'"
cache: true
cache_timeout: 3600ansible -i inventory/netbox.yml all -m ping
ansible -i inventory/netbox.yml tag_backup_daily -m debug -a "msg='Running backup'"Result: Zero-touch, real-time inventory that reflects your NetBox source of truth instantly.
You’ve now built a bulletproof netbox ansible dynamic inventory that syncs live from NetBox—devices, IPs, groups, and all. This eliminates stale inventories forever, letting you run playbooks against the exact state of your infrastructure. Scale it with caching for high-volume runs or extend via custom fields for even smarter grouping.
—
Featured background images in this series by Logan Voss, Creative Engineer. View his portfolio at loganvoss.com.