Skip to content

Cisco NDFC Network as Code (NaC) Integration

Cisco NDFC Network as Code (NaC) Integration

Section titled “Cisco NDFC Network as Code (NaC) Integration”

MetalSoft integrates with Cisco NDFC (Nexus Dashboard Fabric Controller) using the Network as Code (NaC) approach for the write path, and direct read-only NDFC API access for the read path.

In NaC mode, MetalSoft does not push configuration changes directly to NDFC. Instead, it writes generated NaC YAML files to a Git repository provided by the operator. A separate Ansible pipeline — managed by the operator — is responsible for applying those changes to the network.

This design allows operators to:

  • Review and modify changes before they are applied (via Merge Requests)
  • Use standard GitOps tooling and audit trails
  • Keep NDFC credentials read-only within MetalSoft
  • Cisco NDFC controller with at least one VXLAN EVPN fabric
  • A Git repository accessible from the MetalSoft global controller, initialized with a default branch
  • Switches managed by NDFC

Create a Git repository that will hold the NaC YAML files. The default branch must be initialized (at least one commit).

Refer to the netascode/ansible-dc-vxlan project documentation for the initial Ansible collection setup and expected folder structure.

2. Generate a Git Personal Access Token (PAT)

Section titled “2. Generate a Git Personal Access Token (PAT)”

MetalSoft needs read and write access to the repository. Generate a PAT with the following permissions:

ModeRequired Permissions
Direct pushRead and write repository contents
Merge Request modeRead/write contents + create branches + create Merge Requests

In Merge Request mode, MetalSoft creates a branch named metalsoft/pending and opens a MR from that branch into the configured main branch. The operator is responsible for reviewing and merging it.

3. Configure the Network Device Controller in MetalSoft

Section titled “3. Configure the Network Device Controller in MetalSoft”

In the MetalSoft Admin UI, go to Sidebar → Network Devices → Network Device Controllers and click Add network device controller.

  • Set the Driver to Cisco NDFC
  • The NDFC credentials are used for read-only access only — it is recommended to use a read-only NDFC account
  • In the Options (JSON) field, provide a configuration object in the following format:
{
"writeMode": "nac",
"git": {
"repoUrl": "https://git.host/path/to/repo.git",
"branch": "main",
"authMethod": "token",
"authTokenSecretId": 707,
"useMergeRequest": true,
"provider": "gitlab",
"repoBasePath": "host_vars"
}
}

Field reference:

FieldRequiredDescription
writeModeYesMust be "nac"
git.repoUrlYesHTTPS URL of the Git repository
git.branchYesThe main branch (holds approved .nac.yaml files). MetalSoft pushes directly here if useMergeRequest is false
git.authMethodYesMust be "token"
git.authTokenNoPAT in plaintext (not recommended)
git.authTokenSecretIdNoID of a MetalSoft Secret (recommended over authToken)
git.useMergeRequestNoIf true, MetalSoft pushes to metalsoft/pending and opens a MR to branch
git.providerConditionalRequired when useMergeRequest is true. Must be "gitlab" or "github". Private GitLab installations are supported.
git.repoBasePathYesPath in the repo where MetalSoft creates the NaC folder structure (typically "host_vars")

Storing the token as a Secret (recommended):

  1. Go to Admin UI → Sidebar → Variables & Secrets → Secrets
  2. Click Add Secret with usage HTTPRequest
  3. Note the allocated ID and set it in authTokenSecretId

Files written by MetalSoft (with repoBasePath: "host_vars"):

host_vars/<NDFC_FABRIC_NAME>/topology_switches.nac.yaml
host_vars/<NDFC_FABRIC_NAME>/networks.nac.yaml
host_vars/<NDFC_FABRIC_NAME>/vrfs.nac.yaml

In the MetalSoft Fabric Manager UI, add a Fabric corresponding to the fabric in NDFC:

  • The Name can be anything
  • The External ID must exactly match the fabric name in NDFC

After configuring the fabric, activate it.

Go to Sidebar → Network Devices and click Add Network Device for each switch:

  • Name must match the device name in NDFC exactly
  • Driver must be Cisco NDFC
  • Controller must reference the Network Device Controller created above
  • Credentials can be dummy values — MetalSoft reads from NDFC via the controller and writes via Git, not directly to the switches

After adding the switches, go to the Fabric page and add each switch to the fabric in the Topology section.

To use an existing NDFC Network in MetalSoft without recreating it:

  1. Create a Logical Network in MetalSoft with matching sub-resources (VLAN, VNI, subnet, etc.)
  2. Set the externalId field on the Logical Network to match its name in NDFC

To use an existing NDFC VRF, create a Route Domain in MetalSoft and set its VRF name to match the one in NDFC. Setting an externalId on the Route Domain is supported but not required — matching the VRF name is sufficient.

During a MetalSoft infrastructure deployment, whenever the provisioner generates configuration changes for NDFC-managed switches, it writes those changes as edits to the .nac.yaml files in the Git repository.

Direct push mode (useMergeRequest: false): Changes are committed and pushed directly to the configured branch.

Merge Request mode (useMergeRequest: true):

  1. MetalSoft rebases metalsoft/pending on top of the latest branch
  2. Commits the generated changes to metalsoft/pending
  3. Creates (or updates) a MR from metalsoft/pendingbranch

The metalsoft/pending branch is always rebased on the latest branch before each push, ensuring the pending changes stay up to date. Multiple infrastructure deployments may accumulate as separate commits within the same MR.

A job named await_ndfc_nac_deploy_confirmation appears in the deploy graph and waits for the operator to confirm that the changes have been applied to the network.

Once the NaC changes have been successfully applied (via Ansible or another mechanism), the operator confirms them by calling:

POST <METALSOFT_API_URL>/api/v2/network-device-controllers/{networkDeviceControllerId}/actions/deploy-confirm

This single call unblocks all pending deployments that were waiting for confirmation, regardless of how many commits are in the MR.