No Null Networking/ modern networking
← Writing
Automation12 August 20263 min read

Nornir is the automation framework network engineers actually needed

Ansible taught a generation of us to automate, then started getting in the way. What changes when your automation is just Python.

Tom Chaplin
Tom Chaplin
Senior Network Automation Engineer

The first time an Ansible playbook took eleven minutes to push a description change to forty switches, I assumed I'd written it badly. The second time, I read the source. I hadn't written it badly. I'd asked a configuration management tool to behave like a program, and it was doing exactly what it was designed to do instead.

This is the moment most network automation efforts stall. You outgrow YAML before you outgrow the problem. Loops become unreadable, error handling becomes a block/rescue pyramid, and anything resembling a real data structure has to be smuggled through a filter plugin. Nornir solves that in the least glamorous way possible: it stops pretending to be a language.

It's a library, not a runtime

Nornir gives you three things: an inventory, a threaded task runner, and a result object. Everything else is Python you already know. There is no DSL to learn and no execution model to reverse-engineer — if you can read a for loop, you can read the whole framework.

# push a description to every leaf, in parallel, with real errors
from nornir import InitNornir
from nornir_napalm.plugins.tasks import napalm_configure
 
nr = InitNornir(config_file="config.yaml")
leaves = nr.filter(role="leaf", site="lon1")
 
result = leaves.run(
    task=napalm_configure,
    configuration="interface Eth1/1 ; description uplink-to-spine1",
    dry_run=True,
)
 
for host, task_result in result.items():
    if task_result.failed:
        log.error("%s: %s", host, task_result.exception)

Twenty lines, sixty devices, one exception you can actually catch.

The important line is the last block. task_result.exception is a real Python exception object, with a traceback, from the device that failed. Not a string in a log wall. That single difference is what makes it possible to build tooling on top — retries, tickets, a Slack message that names the device and the reason.

From production

At Robinhood the framework we built on this pattern ended up handling most first-line troubleshooting. Not because Nornir is fast — because a typed result object is something an AI agent can be trusted with. Ansible's stdout is not.

Where the inventory really lives

The mistake I see most often is treating the Nornir YAML inventory as the source of truth. It isn't, and it shouldn't be. Your source of truth is NetBox, or Infoblox, or the spreadsheet you're honest enough to admit is running the estate. Nornir takes an inventory plugin, so point it at the real thing and let the YAML die.

Once inventory comes from a system rather than a file, filters stop being lists of hostnames and start being queries: every leaf in this fabric, every device behind that circuit, every box still on the old image. That's when automation stops being a script you run and starts being a capability the team has.

When Ansible is still the right answer

If your automation is a dozen playbooks that a mixed team runs occasionally, Ansible wins on the thing that matters most: everyone can read it without knowing Python. Don't rewrite that. Reach for Nornir when you're building a platform rather than running tasks — when you need tests, retries, concurrency you control, and a result you can hand to another program.

The tool isn't the point. The point is that network automation is software now, and software wants to be written in a language. Nornir just gets out of the way and lets you.

Read next
Kubernetes · 29 July 2026 · 4 min read
Kubernetes networking for network engineers: what a CNI actually does
Kubernetes · 15 July 2026 · 4 min read
Cilium and eBPF, explained without the marketing
Every other Tuesday
One post, no newsletter theatre. Drop your email and I'll send it over.