Summary
nxos_vrf aggregates all of a device's VRFs into a single resource. On brownfield
adoption you import the device's existing VRFs into that resource's state — which always
includes the ever-present default VRF. But the module hardcodes an exclusion of
default from the rendered vrfs map, so on the very next plan the aggregate sees
default in state, doesn't render it, and plans to delete it. NX-OS refuses:
Error: Failed to update object ... Delete of VRF default is not allowed
Because it's one aggregate resource, that failure takes down the entire nxos_vrf
apply — so no VRF on the device can be managed, not just default. Any brownfield
adoption that imports VRFs hits this, whether or not the operator intends to manage
default. Reproduced live on a Nexus 93180YC-FX3.
- Module:
netascode/nac-nxos/nxos 0.3.0
- Provider:
CiscoDevNet/nxos 0.13.1
- Terraform: 1.x (brownfield adoption via
import {} blocks)
Root cause
nxos_vrf.tf builds the per-device vrfs map with a hardcoded && v.name != "default":
# nxos_vrf.tf (0.3.0)
vrf_vrfs_map = { for device in local.devices : device.name =>
{ for vrf in [for v in local.vrfs_rd_dme_format : v
if v.device == device.name && v.name != "default"] : vrf.name => {
...
Nothing else re-adds default, so it is never in after — while import guarantees it is
in before.
Evidence (sanitized)
The DME (GET /api/mo/sys.json) reports a default l3Inst on the device (alongside the
user VRFs), so importing the device's VRFs brings default into nxos_vrf state. The
resulting terraform show -json tfplan then drops it from the rendered set:
nxos_vrf resource_change — VRF key set before/after (sanitized)
{
"note": "nxos_vrf resource_change, VRF key set only (sanitized). before = state after importing the device's VRFs; after = rendered by the module.",
"address": "module.device.module.nxos.nxos_vrf.vrf[\"SWITCH1\"]",
"actions": [
"update"
],
"before.vrfs (in state, from import)": [
"VPC_KA",
"default",
"egress-loadbalance-resolution-",
"management"
],
"after.vrfs (rendered by module)": [
"VPC_KA",
"egress-loadbalance-resolution-",
"management"
],
"deleted": [
"default"
]
}
before (state, from import) contains default; after (rendered by the module) does
not — so the plan deletes it, and the apply fails on the NX-OS rejection above.
Reproduction
- On any NX-OS device (every device has a
default VRF).
- Adopt with the module and
import {} blocks for the device's VRFs, as a brownfield
import would generate.
terraform plan shows nxos_vrf planning to delete default.
terraform apply fails: Delete of VRF default is not allowed, and the whole
nxos_vrf resource apply fails with it.
We've reproduced this live and have the collected DME (GET /api/mo/sys.json) and the full
plan JSON; happy to share sanitized versions or any other detail that would help.
Summary
nxos_vrfaggregates all of a device's VRFs into a single resource. On brownfieldadoption you import the device's existing VRFs into that resource's state — which always
includes the ever-present
defaultVRF. But the module hardcodes an exclusion ofdefaultfrom the rendered vrfs map, so on the very next plan the aggregate seesdefaultin state, doesn't render it, and plans to delete it. NX-OS refuses:Because it's one aggregate resource, that failure takes down the entire
nxos_vrfapply — so no VRF on the device can be managed, not just
default. Any brownfieldadoption that imports VRFs hits this, whether or not the operator intends to manage
default. Reproduced live on a Nexus 93180YC-FX3.netascode/nac-nxos/nxos0.3.0CiscoDevNet/nxos0.13.1import {}blocks)Root cause
nxos_vrf.tfbuilds the per-device vrfs map with a hardcoded&& v.name != "default":Nothing else re-adds
default, so it is never inafter— while import guarantees it isin
before.Evidence (sanitized)
The DME (
GET /api/mo/sys.json) reports adefaultl3Inston the device (alongside theuser VRFs), so importing the device's VRFs brings
defaultintonxos_vrfstate. Theresulting
terraform show -json tfplanthen drops it from the rendered set:nxos_vrfresource_change — VRF key set before/after (sanitized){ "note": "nxos_vrf resource_change, VRF key set only (sanitized). before = state after importing the device's VRFs; after = rendered by the module.", "address": "module.device.module.nxos.nxos_vrf.vrf[\"SWITCH1\"]", "actions": [ "update" ], "before.vrfs (in state, from import)": [ "VPC_KA", "default", "egress-loadbalance-resolution-", "management" ], "after.vrfs (rendered by module)": [ "VPC_KA", "egress-loadbalance-resolution-", "management" ], "deleted": [ "default" ] }before(state, from import) containsdefault;after(rendered by the module) doesnot — so the plan deletes it, and the apply fails on the NX-OS rejection above.
Reproduction
defaultVRF).import {}blocks for the device's VRFs, as a brownfieldimport would generate.
terraform planshowsnxos_vrfplanning to deletedefault.terraform applyfails:Delete of VRF default is not allowed, and the wholenxos_vrfresource apply fails with it.We've reproduced this live and have the collected DME (
GET /api/mo/sys.json) and the fullplan JSON; happy to share sanitized versions or any other detail that would help.