FR
live

Stop configuring switches by hand — network automation does it while you sleep

Ansible, Nornir, and Netmiko turn your network into infrastructure-as-code with Git history, automatic rollback, and drift detection in 2026. Past five devices, automation pays for itself within a month.

Stop configuring switches by hand — ETTAYEB illustration

Ansible turned 11 in February 2026, Nornir 3.5 shipped native dynamic inventory in March, and Netmiko now supports over 150 platforms with 4,200+ GitHub stars. Yet most network teams still open SSH sessions one at a time and paste configuration blocks copied from a notepad. That workflow doesn’t scale past five devices — and the first time a mistyped VLAN ID takes down a trunk at 2 a.m., you’ll wish you’d automated it on a Tuesday afternoon.

The hidden cost of hand-crafting configs

The manual approach wins exactly one round: the first one. SSH in, conf t, paste a block, wr mem. Three minutes per switch. Multiply by 20 access switches in a campus deployment, add manual show run verification on each, and your “quick change” just burned ninety minutes of focused attention — with no record of what was done, by whom, or when.

The real damage shows up weeks later:

  • No rollback. If the change breaks the uplink to the core, you restore from backup one device at a time, hoping the last copy is from yesterday, not last quarter.
  • No drift detection. Six months later, switch 17 is missing spanning-tree portfast because someone skipped it during a 3 a.m. emergency fix. You’ll only find out during the next outage.
  • No reproducibility. The intern who configured switch 12 left in May. Nobody knows why its OSPF redistribution route-map references access-list 142 while the other 19 switches use 101.

Kirk Byers, Netmiko’s creator, put it bluntly in the project README: “Network automation to screen-scraping devices is primarily concerned with gathering output from show commands and with making configuration changes. Netmiko aims to abstract away low-level state control.” Interactive SSH is human screen-scraping. Automation replaces eyes and fingers with declared state.

The three pillars of network automation in 2026

Three tools cover the full spectrum today, from one-off scripts to full GitOps fleet management.

Ansible — agentless idempotence

Ansible remains the easiest entry point. No agent on the devices — everything goes over SSH. The YAML syntax is readable by anyone, and idempotence means running a playbook twice changes nothing on the second pass if the config already matches.

yaml
- name: Deploy VLANs on all access switches
  hosts: access_switches
  gather_facts: false
  tasks:
    - name: Create VLANs
      cisco.ios.ios_vlans:
        config:
          - name: offices
            vlan_id: 100
            state: active
          - name: iot
            vlan_id: 200
            state: active
          - name: guest
            vlan_id: 300
            state: active

That’s 11 lines replacing 60 lines typed manually on every device. Run it through AWX or Ansible Semaphore (the actively maintained open-source alternative to Ansible Tower) and you get execution history, timestamped logs, and an automatic diff of what changed on each device.

Strengths. Agentless, gentle learning curve, mature ecosystem (cisco.ios, arista.eos, junipernetworks.junos, community.network). Ansible network collections cover 60+ platforms.

Weaknesses. Ansible’s sequential push model slows down past 50 devices — each switch is processed one after another. The serial parameter parallelizes in batches, but execution is still single-threaded at its core. For 200 switches, a 3-minute-per-device task clocks in at 600 minutes without native parallelism.

Nornir — native Python, multi-threaded by design

Nornir flips the script entirely. No DSL, no YAML for tasks: you write raw Python. Inventory lives in a YAML file or NetBox, multi-threading is baked in via concurrent.futures, and the framework only handles orchestration — you decide what each task does.

python
from nornir import InitNornir
from nornir_netmiko.tasks import netmiko_send_config
from nornir.core.task import Task, Result

def deploy_snmp(task: Task) -> Result:
    commands = [
        "snmp-server community ETT4YEB RO",
        "snmp-server location DC-Paris",
        "snmp-server contact [email protected]",
    ]
    return task.run(
        task=netmiko_send_config,
        config_commands=commands,
    )

nr = InitNornir(config_file="nornir.yaml")
result = nr.run(task=deploy_snmp)
print(result["switch-core-01"].result)
print(result.failed)

Concurrency is Nornir’s killer feature. On 200 switches, Nornir parallelizes across a thread pool (typically 20-50 concurrent connections). The same SNMP deployment that takes 600 minutes in series drops to 15-30 minutes. And because it’s standard Python, you can pull inventory dynamically from NetBox’s API, push metrics to Prometheus, or chain conditional logic (if "Junos" in task.host.platform).

Nornir 3.5 (March 2026) added native dynamic inventory: your hosts.yaml can reference a plugin that queries NetBox, Nautobot, or any REST API at runtime — no manual pre-generation step.

Netmiko and NAPALM — universal connectivity

Under Nornir’s hood, Netmiko does most of the heavy lifting. Kirk Byers’ library has become the de facto standard for multi-vendor SSH in Python, spanning 150+ platforms from Cisco IOS/NX-OS/XR to MikroTik RouterOS, Huawei, Palo Alto PAN-OS, and Fortinet FortiOS.

python
from netmiko import ConnectHandler

device = {
    "device_type": "cisco_ios",
    "host": "10.0.1.1",
    "username": "admin",
    "password": "vault:secret",
}
with ConnectHandler(**device) as conn:
    output = conn.send_command("show ip ospf neighbor")
    print(output)

NAPALM (Network Automation and Programmability Abstraction Layer with Multivendor support) adds a unified API on top: retrieve facts (get_facts), interfaces (get_interfaces), BGP neighbors (get_bgp_neighbors), or push a configuration candidate with automatic rollback (load_merge_candidate + commit_config). Instead of parsing raw text line by line, you get a Python dictionary:

python
from napalm import get_network_driver

driver = get_network_driver("ios")
with driver("10.0.1.1", "admin", "secret") as device:
    bgp = device.get_bgp_neighbors()
    for peer, data in bgp["global"]["peers"].items():
        print(f"Peer {peer}: up={data['up']}")

GitOps for networking — your config lives in Git, the network follows

The missing link between a manually-run Ansible playbook and real automation is GitOps. The principle is the same one that’s governed Kubernetes since 2017: the source of truth is a Git repository containing the desired configuration, and an operator (or CI/CD pipeline) reconciles the real state with the declared state.

For an enterprise network:

  1. Every change goes through a pull request. An engineer opens a PR modifying vlans.yml or the deploy_qos.yml playbook. The PR triggers an Ansible dry-run or Nornir simulation (check mode) that validates syntax and estimates impact.
  2. A merge triggers deployment. A GitHub Actions or GitLab CI pipeline runs the playbook against production devices, logs the diff in the job output, and notifies the #network-changes Slack channel.
  3. A scheduled job catches drift. Every hour (or nightly), the same playbook runs in check mode: if someone manually changed a line on a switch — say, a forgotten interface shutdown from debugging — the pipeline alerts and optionally auto-remediates.

Ansible AWX (the upstream for Red Hat’s Ansible Automation Platform) and Semaphore support Git webhooks and job scheduling natively. Nornir pairs with any CI/CD orchestrator since it’s just running a Python script.

The immediate win is auditability: every network change has an author, a timestamp, a diff, and an approval. ISO 27001 or SOC 2 compliance — which used to require quarterly manual exports of show run — becomes a Git query.

Which stack for which fleet?

ContextRecommended toolWhy< 10 devicesAnsible + manual playbooksGentle learning curve, readable YAML, agentless10–50 devicesAnsible + Semaphore (CI/CD)Git webhooks, execution history, scheduling50–200 devicesNornir + Netmiko + NetBoxNative multi-threading, full Python control, dynamic inventory> 200 devicesNornir + NAPALM + GitLab CI + drift detectionParallelism, multi-vendor abstraction, GitOps pipelineHeterogeneous multi-vendorNornir + NAPALMUnified API, no per-platform driver neededTeam without Python skillsAnsible + AWXAccessible YAML, web UI, RBAC

Verdict

If you manage fewer than 5 devices, manual CLI is still rational — the overhead of setting up Ansible (inventory, playbook, pipeline) isn’t amortized. But past that threshold, automation stops being optional: every hour spent copy-pasting VLANs is an hour not spent hardening your control plane or auditing CoPP policies.

Start with Ansible on Monday. In a day, you’ll have a playbook that deploys VLANs across all your switches and a cron job that checks compliance every night. Migration to Nornir comes naturally when the playbook’s execution time exceeds your maintenance window — typically around 50 devices running serially.

If your team already knows Python, skip straight to Nornir + Netmiko + NetBox. The parallelism gains and native scripting flexibility justify the upfront investment starting around 20 devices.

Don’t wait. Every quarter you go without Git for your network configs is a quarter where you can’t answer “who changed what, when, and why” — the only question that matters during a production incident.

References

The cyber brief, every Tuesday

The flaws that matter and the patches to apply, in a ten-minute read.

No spam. One-click unsubscribe.
read next

On the same topic

← Back to the feed

Type at least two characters.

navigate open esc dismiss