Skip to content

Conversation

@Dan-Dev-Net
Copy link
Contributor

@Dan-Dev-Net Dan-Dev-Net commented Nov 14, 2025

## Related Issue(s)

Fixes https://github.com/netascode/nac-iosxe/issues/404

**Depends on:**
- Provider PR: CiscoDevNet/terraform-provider-iosxe#369
- Schema PR: netascode/nac-iosxe#594

 **Note:** This PR depends on both provider and schema PRs being merged. **Keep as DRAFT until dependencies resolved.**

## Proposed Changes

Adds Terraform module support for BGP IPv4 MVPN address family configuration, enabling the NAC module to translate YAML configuration into provider resources for MVPN neighbor activation and send-community settings.

### Module Updates (`iosxe_bgp.tf`)

**1. Added MVPN Address Family Resource:**
```hcl
resource "iosxe_bgp_address_family_ipv4_mvpn" "bgp_address_family_ipv4_mvpn" {
  for_each = { for device in local.devices : device.name => device 
    if try(local.device_config[device.name].routing.bgp.address_family.ipv4_mvpn, null) != null }
  
  device  = each.value.name
  asn     = iosxe_bgp.bgp[each.value.name].asn
  af_name = "mvpn"
}

2. Added MVPN Neighbor Locals Block:

locals {
  bgp_ipv4_mvpn_neighbors = flatten([
    for device in local.devices : [
      for neighbor in try(local.device_config[device.name].routing.bgp.address_family.ipv4_mvpn.neighbors, []) : {
        key            = format("%s/%s", device.name, neighbor.ip)
        device         = device.name
        asn            = iosxe_bgp.bgp[device.name].asn
        ip             = neighbor.ip
        activate       = try(neighbor.activate, local.defaults.iosxe.configuration.routing.bgp.address_family.ipv4_mvpn.neighbors.activate, null)
        send_community = try(neighbor.send_community, local.defaults.iosxe.configuration.routing.bgp.address_family.ipv4_mvpn.neighbors.send_community, null)
      }
    ]
  ])
}

3. Added MVPN Neighbor Resource:

resource "iosxe_bgp_ipv4_mvpn_neighbor" "bgp_ipv4_mvpn_neighbor" {
  for_each = { for e in local.bgp_ipv4_mvpn_neighbors : e.key => e }
  
  device         = each.value.device
  asn            = each.value.asn
  ip             = each.value.ip
  activate       = each.value.activate
  send_community = each.value.send_community
  
  depends_on = [iosxe_bgp_neighbor.bgp_neighbor]
}

YAML to Device Configuration Flow

1. User writes NAC YAML:

routing:
  bgp:
    as_number: 65000
    neighbors:
      - ip: 172.16.255.4
        remote_as: 65000
    address_family:
      ipv4_mvpn:
        neighbors:
          - ip: 172.16.255.4
            activate: true
            send_community: extended

2. Module generates Terraform:

resource "iosxe_bgp_address_family_ipv4_mvpn" "..." {
  asn     = "65000"
  af_name = "mvpn"
}

resource "iosxe_bgp_ipv4_mvpn_neighbor" "..." {
  asn            = "65000"
  ip             = "172.16.255.4"
  activate       = true
  send_community = "extended"
}

3. Device receives:

router bgp 65000
  neighbor 172.16.255.4 remote-as 65000
  !
  address-family ipv4 mvpn
    neighbor 172.16.255.4 activate
    neighbor 172.16.255.4 send-community extended
  exit-address-family

Files Changed

Manual Changes:

  • iosxe_bgp.tf - Added MVPN resources and locals (35 lines)

Robot Test(s)

End-to-End Testing:

  • Created NAC YAML test file with MVPN configuration
  • Module loaded successfully with local provider
  • terraform plan generated correct resources (4 resources)
  • terraform apply created all resources successfully
  • Device configuration verified - 100% match to YAML intent
  • Idempotency test - "No changes" on second apply
  • terraform destroy cleaned up correctly

Test Results:

Plan: 4 to add, 0 to change, 0 to destroy.

Resources created:
   iosxe_bgp.bgp
   iosxe_bgp_neighbor.bgp_neighbor  
   iosxe_bgp_address_family_ipv4_mvpn.bgp_address_family_ipv4_mvpn
   iosxe_bgp_ipv4_mvpn_neighbor.bgp_ipv4_mvpn_neighbor

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

# Idempotency test
terraform apply
No changes. Your infrastructure matches the configuration.

Device Verification:

router bgp 65000
 bgp log-neighbor-changes
 no bgp default ipv4-unicast
 neighbor 172.16.255.4 remote-as 65000
 !
 address-family ipv4 mvpn
  neighbor 172.16.255.4 activate
  neighbor 172.16.255.4 send-community extended
 exit-address-family

100% Match to YAML Intent

Cisco IOS-XE Version

Minimum Version: IOS-XE 17.15.1 (per provider requirements)

Tested on:

  • IOS-XE 17.15.1a (C8000V, device 10.81.239.57)

External Repo Link

Related PRs:

Checklist

  • Latest commit is rebased from main
  • Module code follows NAC coding standards
  • Uses try() for optional attributes with defaults
  • Proper depends_on for resource dependencies
  • terraform plan succeeds with test data
  • terraform fmt applied
  • End-to-end testing complete
  • Idempotency verified
  • Device configuration matches YAML intent
  • Follows established patterns (L2VPN EVPN)
  • Provider PR submitted (Issue #402)
  • Schema PR submitted (Issue #403)
  • Git commit message follows team standards

Expected CI Behavior

Expected CI Failure Until Dependencies Resolved

This PR depends on:

  1. Provider PR merged and released
  2. Schema PR merged

CI/CD will fail until both dependencies are available.

Recommended: Keep as DRAFT until dependencies resolved.

- Add iosxe_bgp_address_family_ipv4_mvpn resource mapping
- Add bgp_ipv4_mvpn_neighbors locals block
- Add iosxe_bgp_ipv4_mvpn_neighbor resource mapping
- Support neighbor activate and send_community attributes
- Use try() pattern for optional attributes with defaults

Related to https://github.com/netascode/nac-iosxe/issues/402
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants