Technical Information
Cisco ACI to NetBox Object Mapping
This page describes how ACI object types are mapped to NetBox objects by the integration.
Object Type Mapping Table
| ACI Object | NetBox Object | Key Fields Mapped |
|---|---|---|
topSystem (controller role) | Device | name, serial, role "APIC Controller", APIC version → platform ("Cisco APIC \{version\}") |
topSystem (spine role) | Device | name, serial, role "Spine Switch", platform "Cisco NX-OS" |
topSystem (leaf role) | Device | name, serial, role "Leaf Switch", platform "Cisco NX-OS" |
fabricNode hardware model | DeviceType | Hardware model string → model; manufacturer "Cisco" |
fvCtx | VRF | Context name → name, tenant name → custom_fields.aci_tenant_name, segment → rd |
fvBD + fvSubnet | Prefix | Subnet CIDR → prefix, tenant → custom_fields.aci_tenant_name, BD name → custom_fields.aci_bd_name, status "active" |
l3extSubnet | Prefix | External subnet CIDR → prefix, VRF binding, L3Out name → custom_fields.aci_l3out_name, scope → custom_fields.aci_l3out_subnet_scope, external EPG → custom_fields.aci_external_epg_name |
fvnsVlanInstP | VLANGroup | VLAN pool name → name, allocation mode → description |
| Assigned VLANs (static bindings, L3Out, L2Out) | VLAN | VLAN ID → vid, pool → vlan_group |
pcAggrIf | Interface (LAG) | Port-channel/vPC name → name, type "lag", VLAN and AAEP assignments |
l1PhysIf + ethpmPhysIf + ethpmFcot | Interface | Port name → name, adminSt → enabled, transceiver or speed → type |
l3LbRtdIf | Interface | Name → name, loopbacks typed "virtual", routed physical ports typed from transceiver/speed |
sviIf | Interface | vlan{id} → name, type "virtual", VRF binding |
| Management interface (mgmt0) | Interface | name, type "1000base-t" |
fvSubnet gateway | IPAddress | Gateway CIDR → address, assigned to SVI (anycast-aware) |
l3extIp | IPAddress | IP CIDR → address, tenant name, L3Out name |
topSystem oobMgmtAddr | IPAddress | OOB IP → address, assigned to device as primary_ip4 |
topSystem inbMgmtAddr | IPAddress | In-band management IP → address, assigned to mgmt0-inband interface |
ethpmPhysIf backplaneMac | MACAddress | backplaneMac → mac_address (uppercase), assigned to interface |
Field Mapping Details
Interface Type Mapping
Physical interface type is resolved using a three-tier priority chain:
ethpmFcot.typeName- Cisco transceiver model string (most accurate; used when a transceiver is seated)ethpmPhysIf.operSpeed- Negotiated port speed (used when no transceiver data is available)- Default fallback -
1000base-x-sfp(used when neither source is available)
Speed-based mapping (ethpmPhysIf.operSpeed)
| Operational Speed | NetBox Interface Type |
|---|---|
| 400G | 400gbase-x-qsfpdd |
| 100G | 100gbase-x-qsfp28 |
| 40G | 40gbase-x-qsfpp |
| 25G | 25gbase-x-sfp28 |
| 10G | 10gbase-x-sfpp |
| 1G | 1000base-x-sfp |
| 100M | 100base-tx |
| Unknown / unavailable | 1000base-x-sfp (fallback) |
Transceiver-based mapping (ethpmFcot.typeName)
Cisco transceiver model strings (for example, QSFP-100G-SR4-S, SFP-10G-SR, GLC-T) are matched by pattern to NetBox interface types. Examples:
| Transceiver Pattern | NetBox Interface Type |
|---|---|
QSFP-DD.*400G | 400gbase-x-qsfpdd |
QSFP.*100G, QSFP28, QSFP-100 | 100gbase-x-qsfp28 |
QSFP.*40G, QSFP+ | 40gbase-x-qsfpp |
SFP.*25G, SFP28 | 25gbase-x-sfp28 |
SFP-10G-T, SFP-10G.*BASE-T | 10gbase-t |
SFP.*10G, SFP+ | 10gbase-x-sfpp |
GLC-T, SFP-GE-T, 1000BASE-T | 1000base-t |
GLC-, SFP-GE, 1000BASE | 1000base-x-sfp |
Special cases:
- Management interfaces (
mgmt0,mgmt0-inband): always1000base-t - Loopback interfaces: always
virtual - SVIs: always
virtual
Device Airflow Detection
Node airflow direction is detected from eqptFan attributes and mapped to the NetBox airflow field:
| ACI Fan Direction | NetBox Airflow |
|---|---|
front2back | front-to-rear |
back2front | rear-to-front |
VLAN Sources
VLANs are discovered from three sources:
- Static path bindings (
fvRsPathAtt) on EPGs - L3Out interface attachments
- L2Out attachments
Only VLANs with actual assignments are created. The full VLAN pool range is not expanded.
Prefix Scope (L3Out External Subnets)
The aci_l3out_subnet_scope custom field captures the subnet scope flags from l3extSubnet, which can include values such as import-rtctrl, export-rtctrl, import-security, or combinations thereof.
Anycast Gateway Handling
When multiple SVIs across different leaf switches share the same anycast gateway IP (a common ACI pattern), the integration tracks all associated SVI interfaces in aci_gateway_interfaces_json on the IP address object rather than creating duplicate IP address entries.
Custom Fields
All custom fields are created by the integration and set to read-only in the NetBox UI.
Device Custom Fields
| Custom Field | Type | Purpose |
|---|---|---|
aci_fabric | Text | Fabric identifier (from topSystem.fabricDomain, falls back to SITE_NAME) |
aci_pod | Text | Pod ID |
aci_node_id | Text | ACI node ID |
aci_rack | Text | ACI rack attribute |
Interface Custom Fields
| Custom Field | Type | Purpose |
|---|---|---|
aci_aaep_name | Text | Attachable Access Entity Profile (AAEP) name |
aci_policy_group | Text | Leaf Interface Policy Group assigned to this interface |
aci_static_binding_summary | Text | Summary of EPG static path bindings on this interface |
aci_vpc_domain | JSON | vPC domain name, peer node ID, and peer interface (LAG interfaces only) |
aci_l3out_name | Text | L3Out name (for routed physical ports) |
aci_annotation | Text | ACI object annotation (provisioning source) |
VRF Custom Fields
| Custom Field | Type | Purpose |
|---|---|---|
aci_tenant_name | Text | ACI tenant that owns the VRF context |
aci_l3out_summary | JSON | Summary of L3Outs associated with this VRF (name, tenant, routing protocol) |
aci_annotation | Text | ACI object annotation (provisioning source) |
Prefix Custom Fields
| Custom Field | Type | Purpose |
|---|---|---|
aci_tenant_name | Text | ACI tenant that owns the bridge domain or L3Out |
aci_bd_name | Text | Bridge domain name (for BD subnet prefixes) |
aci_l3out_name | Text | L3Out name (for external subnet prefixes) |
aci_l3out_subnet_scope | Text | L3Out subnet scope flags |
aci_external_epg_name | Text | External EPG (instP) name |
aci_annotation | Text | ACI object annotation (provisioning source) |
IP Address Custom Fields
| Custom Field | Type | Purpose |
|---|---|---|
aci_tenant_name | Text | ACI tenant |
aci_bd_name | Text | Bridge domain name (for BD gateway IPs) |
aci_l3out_name | Text | L3Out name (for L3Out interface IPs) |
aci_gateway_interfaces_json | JSON | SVI interfaces carrying this anycast gateway IP |
aci_l3out_interfaces_json | JSON | L3Out interfaces carrying this IP across border leaf nodes |
aci_annotation | Text | ACI object annotation (provisioning source) |
VLAN Custom Fields
| Custom Field | Type | Purpose |
|---|---|---|
aci_vlan_pools | JSON | All ACI VLAN pools containing this VLAN ID (populated when a VLAN belongs to multiple pools) |
VLAN Group Custom Fields
| Custom Field | Type | Purpose |
|---|---|---|
aci_annotation | Text | ACI object annotation (provisioning source) |
Configuration Parameters
config Parameters
| Parameter | Required | Default | Description |
|---|---|---|---|
APIC_URL | Yes | - | APIC controller URL (e.g. https://apic.example.com) |
APIC_USERNAME | Yes | - | APIC username |
APIC_PASSWORD | Yes | - | APIC password |
SITE_NAME | No | "ACI Fabric" | NetBox site name for this fabric. Ignored for device site assignment when POD_SITE_MAP is set. |
POD_SITE_MAP | No | - | Maps ACI pod IDs to NetBox site names for MultiPOD fabrics. See MultiPOD site mapping. |
BOOTSTRAP | No | false | When true, creates static entities only without connecting to the APIC |
SKIP_SSL | No | false | When true, disables SSL certificate verification for APIC connections |
scope Parameters
Scope parameters limit which fabric objects are ingested. Configure them under a scope key in the policy definition (separate from config).
| Parameter | Type | Default | Description |
|---|---|---|---|
tenants | List of strings | ["*"] | Restrict ingestion to specific ACI tenants. Use ["*"] or omit to ingest all tenants. |
pods | List of strings | ["*"] | Restrict ingestion to specific pod IDs (e.g. ["1", "2"]). Use ["*"] or omit to ingest all pods. |
The scope: key must be present in the policy definition even when no filtering is configured — leave it empty to ingest all tenants and pods.
Tenant scope applies to VRFs, prefixes, L3Out prefixes, subnets, bridge domains, and L3Outs. Pod scope applies to fabric nodes, physical interfaces, and L3 interfaces. Interfaces are not tenant-scoped - they are filtered by pod only.
The integration validates configured tenant and pod values against the live fabric at startup and raises an error if any are not found.
Example agent.yaml - no filtering (ingest everything):
policies:
worker:
cisco_aci_worker:
config:
package: nbl-cisco-aci
APIC_URL: ${APIC_URL}
APIC_USERNAME: ${APIC_USERNAME}
APIC_PASSWORD: ${APIC_PASSWORD}
scope:
Example agent.yaml - with tenant and pod filtering:
policies:
worker:
cisco_aci_worker:
config:
package: nbl-cisco-aci
APIC_URL: ${APIC_URL}
APIC_USERNAME: ${APIC_USERNAME}
APIC_PASSWORD: ${APIC_PASSWORD}
scope:
tenants:
- Production
- DMZ
pods:
- "1"
MultiPOD Site Mapping
For MultiPOD fabrics where each pod is a physically separate datacenter, use POD_SITE_MAP instead of SITE_NAME to assign devices to the correct site based on their pod.
POD_SITE_MAP accepts a YAML dict mapping pod IDs to site names:
config:
APIC_URL: ${APIC_URL}
APIC_USERNAME: ${APIC_USERNAME}
APIC_PASSWORD: ${APIC_PASSWORD}
POD_SITE_MAP:
"1": "Datacenter A"
"2": "Datacenter B"
When passed as an environment variable, use the comma-and-colon form:
POD_SITE_MAP="1:Datacenter A,2:Datacenter B"
Behavior:
- One NetBox site entity is created per distinct site name in the map.
- Every device (APIC controllers and switches) is assigned to the site matching its pod.
SITE_NAMEis ignored for device site assignment whenPOD_SITE_MAPis set. A warning is logged if both are configured.- The integration validates the map at startup: every configured pod must exist in the fabric, and every in-scope pod must have a mapping. Misconfiguration raises an error before any data is synced.
Tags
The integration applies the following tags to every object it ingests:
| Tag | Applied to | Purpose |
|---|---|---|
cisco | All objects | Vendor tag |
aci | All objects | Technology tag |
discovered | All objects | Indicates automated discovery origin |
aci-{apic-hostname} | All objects | Unique per-fabric tag derived from the APIC hostname. Enables filtering by fabric in NetBox and supports multi-fabric deployments. |
tenant-{tenant-name} | VRFs, Prefixes | Tags objects with their ACI tenant name |
The per-fabric aci-{apic-hostname} tag is created from the hostname portion of APIC_URL (for example, aci-apic.example.com). When running multiple integration instances against different fabrics, this tag lets you identify which objects came from which fabric.
Bootstrap Mode
When BOOTSTRAP is set to true, the integration creates the following without connecting to the APIC:
- All ACI-specific custom fields
- A "Cisco" manufacturer entry
- Device roles: APIC Controller, Spine Switch, Leaf Switch
Use bootstrap mode on the initial setup only. Set it to false for all subsequent runs.
Authentication
The integration authenticates to the APIC using a username and password via a POST to /api/aaaLogin.json. The session cookie (APIC-cookie) is managed automatically by the HTTP client for subsequent API requests.
Sync Behavior
- Direction: One-way, ACI to NetBox
- Object deletion: The integration does not delete NetBox objects. Objects removed from the ACI fabric are not automatically decommissioned in NetBox.
- Idempotency: Subsequent runs update existing NetBox objects rather than creating duplicates. The Diode SDK handles conflict resolution.
- Scope: The full fabric is synced by default. Optional tenant and pod scope filtering is available (see Scope Parameters).
- Multi-fabric: Each agent instance is configured for a single APIC. Run a separate agent instance per fabric.
Known Limitations
- On large fabrics, physical interface queries may return a 503 error from the APIC when the result set exceeds 100,000 objects. The integration retries 503 query-timeout errors (up to 5 times), but does not retry "dataset too large" errors.
- Full EPG and contract modeling is not included. Only lightweight EPG metadata (static binding summaries) is captured via custom fields.
- Endpoint (workload) discovery is not supported.
- VRF scope filtering is not available - VRFs are always synced for the configured tenants (or all tenants if no tenant scope is set).