Driving network automation from a source of truth¶
Automation is only ever as good as the data it runs on. This article covers the source of truth — the authoritative system that holds your network's intended state — why it matters, how NetBox, Nautobot, and Git each play the role, and the pull → render → deploy → verify loop that turns that data into enforced configuration.
Intended state vs. operational state¶
Two ideas have to stay distinct:
- Intended state is what the network should be — which devices exist, their roles, IP addressing, VLANs, sites, and interconnections. It lives in the source of truth.
- Operational state is what the network actually is, read back from the devices themselves.
A source of truth (SoT) holds the intended state; devices only realize it. The device running-config and the notes on an engineer's laptop are downstream — never authoritative. Automation's whole job is to make operational state match intended state, and to flag the gap when they differ. That gap is configuration drift, and reconciling it is the foundation of configuration compliance.
Why one authoritative dataset¶
Without an SoT, the "truth" is scattered across spreadsheets, wikis, and the running-config of hundreds of devices — and every copy drifts independently. Nobody can say with confidence which VLAN IDs are in use, which prefixes are free, or why a given interface is configured the way it is.
With an SoT there is exactly one authoritative dataset driving every automation run, so configurations become consistent, auditable, and reproducible. A change is made once, in one place, and automation propagates it everywhere. This is the shift the industry summarizes as "playbooks read truth from an API, not assumptions."
Two kinds of source of truth¶
In practice you usually run two complementary sources of truth, one for data and one for code:
| SoT | Holds | Typical tools |
|---|---|---|
| Infrastructure data | Sites, racks, devices, interfaces, prefixes, VLANs, roles | NetBox, Nautobot |
| Configuration code | Templates, playbooks, variable files, pipeline definitions | Git |
NetBox and Nautobot merge the traditional disciplines of IP address management (IPAM) and data-center infrastructure management (DCIM) into one queryable model, exposed over REST and GraphQL APIs. They are deliberately a system of record, not a controller — they describe intent and leave enforcement to your automation tooling.
Git is the source of truth for the configuration code itself. Combined with review and CI/CD, that gives you the GitOps model: the repository is authoritative, every change is versioned and reviewed, and the pipeline renders and deploys it.
The integration loop¶
Whichever systems you use, the pattern is the same four steps:
- Pull data from the SoT through its REST or GraphQL API — devices, interfaces, IPs, VLANs.
- Render configuration from that data, typically with Jinja2 templates.
- Deploy the rendered config with Ansible, Terraform, or Python.
- Verify that operational state now matches intent, and report any drift.
The change always starts in the SoT. When 200 devices need a new VLAN, you edit the VLAN once in NetBox; automation then renders and deploys it to all 200 consistently. Editing the devices directly bypasses the SoT and immediately reintroduces drift.
NetBox as a dynamic Ansible inventory¶
The most common integration is to let NetBox be your Ansible inventory. Instead of a static hosts
file that rots the moment the network changes, the
netbox.netbox.nb_inventory
plugin queries NetBox at run time, so the device list and its variables always reflect the source of
truth. Install the collection with ansible-galaxy collection install netbox.netbox, then point an
inventory file at your instance:
# inventory/netbox.yml — a dynamic inventory pulled live from the SoT
plugin: netbox.netbox.nb_inventory
api_endpoint: https://netbox.example.com
# The API token is read from the NETBOX_TOKEN environment variable — never commit it.
validate_certs: true
group_by:
- device_roles
- sites
query_filters:
- status: active # skip planned/decommissioned devices
The query_filters line is a small but important habit: it keeps pre-production and
decommissioned devices out of the live inventory, so automation only ever touches what is really in
service. With the inventory in place, a playbook renders each device's config straight from
SoT-supplied variables:
- name: Configure from source of truth
hosts: all
gather_facts: false
tasks:
- name: Build config from NetBox-provided variables
ansible.builtin.template:
src: templates/device.j2
dest: "rendered/{{ inventory_hostname }}.cfg"
delegate_to: localhost
No hand-maintained variable files sit between NetBox and the template, so there is nothing to drift out of sync.
Modeling data so it stays trustworthy¶
A source of truth is only as good as its data model. The value of NetBox and Nautobot over a spreadsheet is normalization: every fact lives in exactly one place and is referenced elsewhere. A VLAN, a prefix, or a device role is defined once and reused. A device gets its site, role, and platform by reference; an interface gets its IP from the IPAM module.
That structure prevents the contradictions that plague spreadsheets — the same VLAN with two names, or an address assigned twice — because the model simply won't allow them. The payoff for automation is data that is queryable and consistent: your rendering step asks the API "what interfaces does spine-01 have, and what IPs?" and gets structured, validated answers it can feed straight into a template.
Closing the loop: drift and audit¶
A source of truth becomes powerful when the network is both driven from it and checked against it. The full loop reads intended state from the SoT, renders and deploys config, then reads back the running state and compares. Any difference is drift, and it can raise an alert or trigger remediation — modern platforms like Nautobot can detect drift and trigger corrective jobs on a schedule.
This also transforms audits. Because the running config was rendered from the SoT, proving that every production VLAN is authorized collapses to a single comparison: rendered-from-SoT versus running-config across the fleet. Zero drift means every VLAN traces back to an approved SoT entry — a report that would otherwise take days by hand.
Key takeaways¶
- A source of truth holds intended state; devices realize it but are never authoritative.
- Run two SoTs: NetBox/Nautobot for infrastructure data (IPAM/DCIM), Git for configuration code.
- The pattern is pull → render → deploy → verify — data, not memory, drives every change.
- A dynamic inventory (
netbox.netbox.nb_inventory) keeps automation aligned with the SoT automatically; filter it to active devices. - Normalization is what makes SoT data trustworthy: every fact defined once, referenced everywhere.
- Make the change in the SoT first, then let automation propagate it; the difference between intended and operational state is drift, and the closed loop is what catches it.
Sources: NetBox Labs — The Premier Network Source of Truth,
NetBox documentation,
Nautobot — Network Source of Truth & Automation Platform,
Ansible — netbox.netbox.nb_inventory inventory plugin.