The short version
- NetBox combines IPAM and DCIM with APIs into the one instance that holds the network's intended state — the documentation explicitly calls it the “source of truth” to power network automation.
- The docs are unambiguous: NetBox represents the desired state of a network versus its operational state — automated import of live network state is strongly discouraged, and data should be vetted by a human.
- Ansible reads its inventory straight from NetBox (nb_inventory, groups built from sites and roles); the cisco.ios collection enforces the intended state with resource modules such as ios_vlans and ios_interfaces.
- Getting started does not require perfect data: one domain, one site — then the documented truth grows, and from that point every change runs through it.
The scene exists in almost every grown network: a VLAN needs to reach twelve switches, someone opens the IP list — last edited four months ago by a colleague who has since left. Next to it a second list on the team share, and a third in the head of the longest-serving engineer. You cannot automate on that. Not because the tooling is missing, but because nobody can say what is supposed to be true.
That gap is exactly what a source of truth fills: the one instance that holds the network's intended state and makes it machine-readable. The most widely used tool for it is NetBox — its documentation describes it as the combination of IP address management (IPAM) and infrastructure management (DCIM) with powerful APIs, explicitly the “source of truth” to power network automation. Since its open-source release in 2016, thousands of organisations have used it precisely that way.
The intended state is the point — not the current one
The most common false start looks sensible: harvest the existing network automatically first, then at least there is data. The NetBox documentation advises explicitly against it: NetBox represents the desired state of a network versus its operational state — and automated import of live network state is strongly discouraged. Data should be vetted by a human before it goes in.
The reason is not purism. Importing the current state promotes the sprawl to a standard: the forgotten VLAN 99, the trunk configuration from 2019, the address from the wrong range — the import turns all of it into documented truth. From then on you are automating the accident, just faster.
What goes in — and in which order
NetBox models the objects a network actually consists of: sites, devices and device types, interfaces, cabling, VLANs, VRFs, prefixes and IP addresses. The order of entry is not a matter of taste — it decides whether the data holds:
Sites and devices
Sites, device types, devices with roles (access, distribution, core, firewall). The role later becomes the anchor of the automation.
Cabling
Uplinks and stacks as documented connections. Only then do statements like “sits behind” become checkable.
IPAM top-down
Aggregates and prefixes first, individual addresses second. An IP without prefix context is a sticky note, not a record.
VLANs and VRFs
With names, numbers and ownership — the level where segmentation plans become concrete.
Primary IPs and platform
Every device gets its management address and platform attribute. Exactly these fields make the device reachable for tooling.
And: no complete inventory is required before the first value appears. One domain — say, one site with its access switches — complete and vetted is worth more than the whole network half-done. From then on the rule that makes the difference applies: every change goes through the source of truth first. How to get a grown network into a documentable order in the first place is covered in our piece on tidying a grown company network.
Where Ansible takes over
The first move that pays off immediately: Ansible stops maintaining its own inventory. The nb_inventory plugin of the netbox.netbox collection reads hosts straight from NetBox and builds groups from what is recorded there anyway — sites, roles, platforms, tags. The host list that used to run alongside reality is simply gone.
For enforcing state on Cisco devices there is the cisco.ios collection (currently version 11.5) — with resource modules for exactly the objects modelled in NetBox: ios_vlans, ios_interfaces, ios_l2_interfaces and ios_l3_interfaces, plus ios_ospfv2, ios_acls, ios_ntp_global and more. The intended state comes from NetBox; the module establishes it — instead of typing command sequences that end differently on every device.
- Never keep a second inventory. Hosts, groups and reachability come from NetBox — a separate list is the beginning of the next lie.
- Render intent, don't collect commands. Describe VLANs, interfaces and routing as state, not as a CLI history.
- No run without a dry run. Preview with a change diff first, execute second — the diff before the change is the document you can talk about.
- Roles, not host lists. “All access switches at site X” is a NetBox query — and stays correct when the thirteenth switch arrives.
Try it locally: from reviewed intent to a configuration diff
Download the NetBox lab ZIP and read the instructions and verification commands. It contains two fictional switches, a prepared desired-state inventory, local baseline configurations and a small Python generator. Python 3.10 or later is enough; the exercise needs no extra packages, NetBox instance or credentials.
Read the intent and name the change
After extracting, compare fixture.json with baseline/: sw-ber-01 in lab-berlin should gain VLAN 30 named GUEST. sw-ham-01 in lab-hamburg keeps VLANs 10 and 20. The review marker in the fixture is part of the example; it cannot replace an actual review in your own process.
Render locally
Run python3 -B lab.py from the extracted netbox-lab directory. output/ receives inventory.ini, two configuration snippets, two diff files and report.json. An existing output directory is preserved; the README explains how to run a second example.
Check against the expected result
python3 -B test_lab.py checks the expected files, device targeting and malformed inputs using temporary directories. If Ansible is installed, ansible-inventory can additionally list the generated inventory without contacting devices.
| Artefact | Expected result |
|---|---|
| output/inventory.ini | Two hosts with primary IPs; site_lab_berlin and site_lab_hamburg site groups plus role_access |
| output/diff/sw-ber-01.diff | Adds VLAN 30 / GUEST compared with the local baseline snippet |
| output/diff/sw-ham-01.diff | Empty; the Hamburg configuration snippet remains unchanged |
| output/report.json | changed: sw-ber-01 · unchanged: sw-ham-01 |
The bridge to real NetBox is the data contract. In a production workflow, netbox.netbox.nb_inventory can read devices from the NetBox API, narrow them with device_query_filters, create groups with group_by and include context data as host variables with config_context: true. The download rehearses this handover using a fixed file and a generated INI inventory; it does not implement the plugin. A real integration must verify fields and filters against the deployed NetBox and collection versions.
The loop closes in operations
With event rules, NetBox reports changes on its own: a new prefix or a modified device can trigger a pipeline via webhook instead of waiting for someone to remember. And the drift question — does the network deviate from the intended state? — turns from a suspicion into a recurring run with a result list.
For perspective next to the platforms: NetBox replaces neither Catalyst Center nor the Meraki dashboard — it answers a different question. The division of labour that holds is described in our piece on the Catalyst Center API: NetBox remains the inventory and the intent instance, the platform takes onboarding, software waves and assurance for its device world.
The documented automation change shows this chain in practice. We separate NetBox and data ownership, Ansible execution and API integration with data contracts and failure tests. Start with one domain, maintain its intended state and make changes traceable through it.
Sources
Every evidenced claim in this article can be traced here. The retrieval date shows how fresh the check is.
- Devices — fields and primary IP addressesopens in a new tab
NetBox Labs Docs · retrieved 7 September 2026
- Context Data — arbitrary JSON associated with devicesopens in a new tab
NetBox Labs Docs · retrieved 7 September 2026
- VLANs — identifiers and namesopens in a new tab
NetBox Labs Docs · retrieved 7 September 2026
- How to build your inventory — INI hosts and groupsopens in a new tab
Ansible Community Documentation · retrieved 7 September 2026
- Introduction to NetBox — Serve as a “Source of Truth”opens in a new tab
NetBox Labs Docs · retrieved 7 September 2026
- NetBox Documentationopens in a new tab
NetBox Labs Docs · retrieved 7 September 2026
- Cisco Ios Collection (Version 11.5.0)opens in a new tab
Ansible Community Documentation · retrieved 7 September 2026
- netbox.netbox.nb_inventory inventory — NetBox inventory sourceopens in a new tab
Ansible Community Documentation · retrieved 7 September 2026

