Back to Learn

Data Center automation โ€” management, fault finding & deployment

Operate spine-leaf fabrics the same way across every vendor. This guide walks through day-2 management, telemetry-driven fault finding and safe deployment for Cisco NX-OS/ACI, Arista EOS, Juniper QFX, Nokia SR Linux and Cumulus Linux.

Multi-vendor
VXLAN / EVPN
Cisco NX-OS / ACI
Arista EOS
Juniper QFX
Nokia SR Linux
Cumulus Linux
Aruba CX
Management โ€” model intent once, render per-vendor config
Fault finding โ€” stream telemetry and assert fabric health
Deployment โ€” stage, diff, commit and roll back safely

Setup, key commands & run examples

Topic 1 โ€” vendor-neutral inventory
Management

Describe the fabric once. A normalized inventory (roles, ASNs, links, loopbacks) lets every workflow target Cisco, Arista, Juniper, Nokia and Cumulus from the same source of truth.

Topic 1 โ€” vendor-neutral inventory
yaml
# inventory/fabric.yml
fabric:
  asn_base: 65000
  underlay: ospf            # or ebgp
  overlay: evpn-vxlan
devices:
  spine1: { role: spine, vendor: arista,  mgmt: 10.0.0.11 }
  spine2: { role: spine, vendor: cisco,   mgmt: 10.0.0.12 }
  leaf1:  { role: leaf,  vendor: juniper, mgmt: 10.0.0.21, vtep: 10.255.0.21 }
  leaf2:  { role: leaf,  vendor: nokia,   mgmt: 10.0.0.22, vtep: 10.255.0.22 }
  leaf3:  { role: leaf,  vendor: cumulus, mgmt: 10.0.0.23, vtep: 10.255.0.23 }
manage.py โ€” multi-vendor day-2 management
Management

Use NAPALM/Netmiko drivers keyed off the inventory vendor so one script collects facts and pushes config to any platform in the fabric.

manage.py โ€” multi-vendor day-2 management
python
import napalm

DRIVER = {"cisco": "nxos_ssh", "arista": "eos", "juniper": "junos"}

def connect(dev):
    drv = napalm.get_network_driver(DRIVER[dev["vendor"]])
    return drv(dev["mgmt"], "admin", "secret")

for name, dev in fabric_leaves.items():
    with connect(dev) as conn:
        facts = conn.get_facts()
        print(name, facts["model"], facts["os_version"])
faultfind.py โ€” telemetry-driven troubleshooting
Fault finding

Pull structured state (BGP/EVPN peers, interfaces, VXLAN tunnels) across vendors and assert health. Flag down peers, flapping links and missing VTEPs automatically.

faultfind.py โ€” telemetry-driven troubleshooting
python
def check_evpn(conn, name):
    bgp = conn.get_bgp_neighbors()
    for vrf, data in bgp.items():
        for ip, peer in data["peers"].items():
            if not peer["is_up"]:
                print(f"[FAULT] {name} EVPN peer {ip} DOWN in {vrf}")

def check_interfaces(conn, name):
    for intf, st in conn.get_interfaces().items():
        if intf.startswith("Ethernet") and not st["is_up"] and st["is_enabled"]:
            print(f"[FAULT] {name} {intf} enabled but down")
deploy.py โ€” safe fabric deployment
Deployment

Render per-vendor config from the intent model, stage it as a candidate, diff it, and only commit when the diff is expected. Roll back on validation failure.

deploy.py โ€” safe fabric deployment
python
with connect(dev) as conn:
    conn.load_merge_candidate(config=rendered_config)   # stage
    diff = conn.compare_config()                         # preview
    print(diff)
    if diff and approved(diff):
        conn.commit_config()                             # apply
    else:
        conn.discard_config()                            # abort
    # if post-checks fail: conn.rollback()

Best practices

  • One intent model, many renderers

    Keep a single vendor-neutral description of the fabric and generate per-platform config from it โ€” never hand-edit device CLI per box.

  • Diff before every commit

    Stage config as a candidate and review compare_config() (or gate it in CI) so no fabric change is applied blind.

  • Assert health, don't eyeball it

    Codify fault finding: EVPN peers up, all VTEPs reachable, no error counters climbing, MLAG/EVPN-ESI consistent on both leaves of a pair.

  • Deploy leaf-pairs, not whole rows

    Roll changes one MLAG/ESI pair at a time and verify before moving on, so a bad change never takes out a redundant pair together.

Hands-on exercises

Guided practice tasks โ€” copy the starter snippet, run it against a lab device, and extend it to meet the goal.

Exercise 1
Fabric inventory report

Goal: Loop over every device in fabric.yml, connect with the right driver per vendor, and print role, model and OS version in a table.

exercise_1
python
import yaml, napalm

fabric = yaml.safe_load(open("inventory/fabric.yml"))
DRIVER = {"cisco": "nxos_ssh", "arista": "eos", "juniper": "junos"}

for name, dev in fabric["devices"].items():
    # TODO: connect via DRIVER[dev["vendor"]] and print get_facts()
    ...
Exercise 2
EVPN fault sweep

Goal: Across all leaves, collect BGP/EVPN neighbors and print any peer that is not up, with device name and VRF.

exercise_2
python
for name, dev in leaves.items():
    with connect(dev) as conn:
        bgp = conn.get_bgp_neighbors()
        # TODO: report peers where peer["is_up"] is False
        ...
Exercise 3
Guarded VLAN rollout

Goal: Add a new L2VNI to one leaf pair: stage config, print the diff, and only commit when the diff contains the expected VLAN id.

exercise_3
python
for dev in [leaf1, leaf2]:
    with connect(dev) as conn:
        conn.load_merge_candidate(config=render_l2vni(vlan=120, vni=10120))
        diff = conn.compare_config()
        # TODO: if "120" in diff: conn.commit_config() else conn.discard_config()
        ...

Per-vendor lessons

Drill into management, fault finding and deployment for each vendor.

Curated videos & guides

Checklist โ€” pitfalls, gotchas & verification

Common pitfalls

  • โ€ขPushing config box-by-box from CLI instead of rendering from one intent model โ€” config drift is guaranteed.
  • โ€ขDeploying both leaves of an MLAG/ESI pair at once and dropping the redundant path.
  • โ€ขAssuming every getter/driver behaves identically โ€” NX-OS, EOS and JunOS differ in candidate/commit semantics.

Gotchas to watch

  • โ€ขcompare_config() returns an empty string (not None) when there is no change โ€” test truthiness.
  • โ€ขACI is intent/controller-driven (APIC REST), not CLI โ€” treat it differently from NX-OS leaf switches.
  • โ€ขVXLAN/EVPN faults often hide in the underlay โ€” check OSPF/eBGP and MTU before blaming the overlay.

Verify it works

  • โ€ขAfter deploy, re-read EVPN neighbors and confirm every peer returned to up.
  • โ€ขConfirm all expected VTEPs appear in the overlay and the L2/L3 VNIs are programmed on both pair members.
  • โ€ขDiff running-config against intent post-change to prove zero unexpected drift.

Treat the fabric as one system: a vendor-neutral inventory + intent model lets the same management, fault-finding and deployment workflows run everywhere. Pair these patterns with Nornir or Ansible for fleet-wide execution.