Migrating a brownfield VXLAN EVPN fabric to Cisco NDFC: what Recalculate rejects

You have a VXLAN EVPN fabric that already works, and now it needs to be managed by Cisco NDFC. This post walks through bringing ten Nexus 9300v switches under Nexus Dashboard as a brownfield migration, without rebuilding anything.
Hand-drawn banner: brownfield vxlan evpn to cisco ndfc, nexus dashboard migration, what recalculate rejects

On this page

You have a VXLAN EVPN fabric that works. It was built by hand, or by Ansible, or by a generator script, and it carries production traffic. Now it has to live under Nexus Dashboard Fabric Controller. NDFC can adopt a running fabric without rebuilding it: you create a fabric, discover the switches with their configuration preserved, and let NDFC learn what is already there. That is the brochure. In practice NDFC runs a brownfield check against every switch, refuses to leave migration mode until the parts it checks match its own templates, and then shows you a diff of everything it wants to change. This post walks through one real migration end to end: every error it threw, what each one actually meant, and how the fabric went from unmanaged to In-Sync without a single lost ping during the deploy.

Six steps: mirror the fabric settings from the running config, discover with preserve config, Recalculate as the brownfield check with a loop back to itself until every error is fixed, read the per-switch diff, staged deploy with pings running, and move the source of truth to NDFC's intent.
The migration as it actually ran. Step 3 is a loop: Recalculate, fix what it rejects, run it again.

The fabric NDFC inherited

Ten Nexus 9300v switches on NX-OS 10.6(1)F, carrying the frontend network of an AI cluster. Two spines acting as BGP route reflectors, six leaves in three vPC Fabric Peering pairs, and a border pair with no vPC that routes each VRF to a Palo Alto firewall. The underlay is OSPF with IP unnumbered links borrowing loopback0, the overlay is iBGP EVPN in AS 65100, BUM traffic uses ingress replication. None of it was built by NDFC: a Python generator writes every switch config, and the Nexus section of its validation script runs 134 checks against the live fabric, including "every generated line is in the running-config" for each switch.

Topology: fe-spine1 and fe-spine2 at the top, six leaves below in three vPC Fabric Peering domains, fe-border1 and fe-border2 on the right connected to a PA-VM firewall, and Nexus Dashboard managing the switches through their mgmt0 interfaces.
The fabric before NDFC. Nexus Dashboard 4.3.1 lives at a different site and reaches every switch on mgmt0 only.

The controller is Nexus Dashboard 4.3.1.175 with NDFC, reaching the switches through their management interfaces. Every NDFC step below was an ND REST API call rather than a GUI click, so each one is a request you can repeat. The Nexus Dashboard screenshots were taken in the GUI after the migration, to show where each step left the fabric.

Nexus Dashboard fabric overview for Site-4-frontend: type Data Center VXLAN EVPN iBGP, BGP ASN 65100, config-sync status In sync, deployment Enabled, software version 10.6(1), inventory 10 switches and 3 vPC pairs, 3 networks and 3 VRFs, 848 interfaces with 282 up and 518 down.
Where it ends: Site-4-frontend in Nexus Dashboard, In sync, with 10 switches, 3 vPC pairs, and the 3 networks and 3 VRFs it imported from the running config. The 518 down interfaces are real: counting ports in state down with show interface brief across the ten switches gives the same 518.

The rest of this post is how it got there.

This post is for paying subscribers only

Subscribe to LevelUp I.T. newsletter and stay updated.

Don't miss anything. Get all the latest posts delivered straight to your inbox. It's free!
Great! Check your inbox and click the link to confirm your subscription.
Error! Please enter a valid email address!