Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8f63370
make interface group variables interpolation work
tobiwang Jul 13, 2025
2774160
make config template variables interpolation work with precedence: de…
tobiwang Jul 13, 2025
6089389
Merge pull request #1 from tobiwang/fix_interface_group
tobiwang Jul 13, 2025
030ade9
Merge branch 'main' into fix_configuration_template
tobiwang Jul 13, 2025
d0e31d8
Merge pull request #2 from tobiwang/fix_configuration_template
tobiwang Jul 13, 2025
5210bdc
fix variables interpolation for interface_groups and configuration_te…
tobiwang Jul 13, 2025
0943aeb
fix variables interpolation with precedence: device-level > interface…
tobiwang Jul 14, 2025
ec7563e
fix configuration_template variable interpolation
tobiwang Jul 15, 2025
b4a52ba
Removing interface_group level variables support
tobiwang Jul 16, 2025
d744219
reuse device_variables
tobiwang Jul 16, 2025
462d2d4
fix interface_groups_config with re-using device_variables
tobiwang Jul 16, 2025
b02c5e5
reuse device_variables
tobiwang Jul 16, 2025
89b0381
fix interface_groups_config with re-using device_variables
tobiwang Jul 16, 2025
0008660
fix variable names with using plural
tobiwang Jul 16, 2025
1b6ba59
Merge branch 'main_reduce_vars' into main
tobiwang Jul 16, 2025
9f83cb1
Merge branch 'main' of github.com:tobiwang/terraform-nxos-nac-nxos in…
tobiwang Jul 29, 2025
345c966
fix README.md
tobiwang Jul 29, 2025
bd1792e
feat: Add comprehensive VPC (Virtual Port Channel) support
tobiwang Jul 29, 2025
bb15c1a
fix interface_port_channel ospf
tobiwang Jul 29, 2025
26b6214
fix interface_port_channel ospf
tobiwang Jul 29, 2025
24668e0
fix virtual peerlink
tobiwang Jul 29, 2025
74fb5f5
fix
tobiwang Jul 29, 2025
0391603
fix
tobiwang Jul 29, 2025
1ad6412
fix yamllint error issue of defaults.yaml
tobiwang Jul 29, 2025
c36b3e7
re-order vpc related resources
tobiwang Jul 29, 2025
d7c839d
using null (omit) as a last resort instead of hardcording
tobiwang Jul 30, 2025
9e7f4aa
vpc_domain in defaults.yaml
tobiwang Jul 30, 2025
7418dc5
fix defaults value reference
tobiwang Aug 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ module "nxos" {
| [nxos_svi_interface.svi_interface](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/svi_interface) | resource |
| [nxos_svi_interface_vrf.svi_interface_vrf](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/svi_interface_vrf) | resource |
| [nxos_system.system](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/system) | resource |
| [nxos_vpc_domain.vpc_domain](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vpc_domain) | resource |
| [nxos_vpc_instance.vpc_instance](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vpc_instance) | resource |
| [nxos_vpc_interface.vpc_interface](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vpc_interface) | resource |
| [nxos_vpc_keepalive.vpc_keepalive](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vpc_keepalive) | resource |
| [nxos_vpc_peerlink.vpc_peerlink](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vpc_peerlink) | resource |
| [nxos_vrf.vrf](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vrf) | resource |
| [nxos_vrf_address_family.vrf_address_family](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vrf_address_family) | resource |
| [nxos_vrf_route_target.vrf_route_target](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vrf_route_target) | resource |
Expand Down
2 changes: 2 additions & 0 deletions defaults/defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ defaults:
additive: false
no_community: false
set_criteria: none
vpc_domain:
admin_state: true
6 changes: 5 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ resource "nxos_save_config" "save_config" {
nxos_bridge_domain.bridge_domain,
nxos_vrf_route_target.vrf_route_target,
nxos_ipv4_vrf.ipv4_vrf,
nxos_ipv4_vrf.ipv4_vrf_default
nxos_ipv4_vrf.ipv4_vrf_default,
nxos_vpc_domain.vpc_domain,
nxos_vpc_keepalive.vpc_keepalive,
nxos_vpc_peerlink.vpc_peerlink,
nxos_vpc_interface.vpc_interface
]
}
4 changes: 2 additions & 2 deletions nxos_ospf.tf
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ locals {
}

resource "nxos_ospf_interface" "ospf_interface" {
for_each = { for v in local.ospf_interfaces : v.key => v if v.ospf_process_name != null }
for_each = { for v in local.ospf_interfaces : v.key => v if try(v.ospf_process_name, null) != null }
device = each.value.device
instance_name = each.value.ospf_process_name
vrf_name = nxos_ospf_vrf.ospf_vrf["${each.value.device}/${each.value.ospf_process_name}/${each.value.vrf}"].name
Expand All @@ -116,7 +116,7 @@ resource "nxos_ospf_interface" "ospf_interface" {
}

resource "nxos_ospf_authentication" "ospf_authentication" {
for_each = { for v in local.ospf_interfaces : v.key => v if v.ospf_authentication_type == "simple" || v.ospf_authentication_type == "md5" }
for_each = { for v in local.ospf_interfaces : v.key => v if try(v.ospf_authentication_type, null) == "simple" || try(v.ospf_authentication_type, null) == "md5" }
device = each.value.device
instance_name = each.value.ospf_process_name
vrf_name = each.value.vrf
Expand Down
165 changes: 165 additions & 0 deletions nxos_vpc.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
locals {
vpc_domains = flatten([
for device in local.devices : [
{
key = format("%s/%s", device.name, local.device_config[device.name].vpc_domain.domain_id)
device = device.name
domain_id = try(local.device_config[device.name].vpc_domain.domain_id, local.defaults.nxos.devices.configuration.vpc_domain.domain_id, null)
admin_state = try(local.device_config[device.name].vpc_domain.admin_state, local.defaults.nxos.devices.configuration.vpc_domain.admin_state, null)
auto_recovery = try(local.device_config[device.name].vpc_domain.auto_recovery, local.defaults.nxos.devices.configuration.vpc_domain.auto_recovery, null)
auto_recovery_interval = try(local.device_config[device.name].vpc_domain.auto_recovery_interval, local.defaults.nxos.devices.configuration.vpc_domain.auto_recovery_interval, null)
delay_restore_orphan_port = try(local.device_config[device.name].vpc_domain.delay_restore_orphan_port, local.defaults.nxos.devices.configuration.vpc_domain.delay_restore_orphan_port, null)
delay_restore_svi = try(local.device_config[device.name].vpc_domain.delay_restore_svi, local.defaults.nxos.devices.configuration.vpc_domain.delay_restore_svi, null)
delay_restore_vpc = try(local.device_config[device.name].vpc_domain.delay_restore_vpc, local.defaults.nxos.devices.configuration.vpc_domain.delay_restore_vpc, null)
dscp = try(local.device_config[device.name].vpc_domain.dscp, local.defaults.nxos.devices.configuration.vpc_domain.dscp, null)
fast_convergence = try(local.device_config[device.name].vpc_domain.fast_convergence, local.defaults.nxos.devices.configuration.vpc_domain.fast_convergence, null)
graceful_consistency_check = try(local.device_config[device.name].vpc_domain.graceful_consistency_check, local.defaults.nxos.devices.configuration.vpc_domain.graceful_consistency_check, null)
l3_peer_router = try(local.device_config[device.name].vpc_domain.l3_peer_router, local.defaults.nxos.devices.configuration.vpc_domain.l3_peer_router, null)
l3_peer_router_syslog = try(local.device_config[device.name].vpc_domain.l3_peer_router_syslog, local.defaults.nxos.devices.configuration.vpc_domain.l3_peer_router_syslog, null)
l3_peer_router_syslog_interval = try(local.device_config[device.name].vpc_domain.l3_peer_router_syslog_interval, local.defaults.nxos.devices.configuration.vpc_domain.l3_peer_router_syslog_interval, null)
peer_gateway = try(local.device_config[device.name].vpc_domain.peer_gateway, local.defaults.nxos.devices.configuration.vpc_domain.peer_gateway, null)
virtual_peerlink_destination_ip = try(local.device_config[device.name].vpc_domain.virtual_peerlink_destination_ip, local.defaults.nxos.devices.configuration.vpc_domain.virtual_peerlink_destination_ip, null)
peer_switch = try(local.device_config[device.name].vpc_domain.peer_switch, local.defaults.nxos.devices.configuration.vpc_domain.peer_switch, null)
role_priority = try(local.device_config[device.name].vpc_domain.role_priority, local.defaults.nxos.devices.configuration.vpc_domain.role_priority, null)
system_mac = try(upper(local.device_config[device.name].vpc_domain.system_mac), upper(local.defaults.nxos.devices.configuration.vpc_domain.system_mac), null)
system_priority = try(local.device_config[device.name].vpc_domain.system_priority, local.defaults.nxos.devices.configuration.vpc_domain.system_priority, null)
track = try(local.device_config[device.name].vpc_domain.track, local.defaults.nxos.devices.configuration.vpc_domain.track, null)
virtual_peerlink_source_ip = try(local.device_config[device.name].vpc_domain.virtual_peerlink_source_ip, local.defaults.nxos.devices.configuration.vpc_domain.virtual_peerlink_source_ip, null)
peer_keepalive = try(local.device_config[device.name].vpc_domain.peer_keepalive, {})
}
] if try(local.device_config[device.name].vpc_domain, null) != null
])
}

resource "nxos_vpc_instance" "vpc_instance" {
for_each = { for vpc_domain in local.vpc_domains : vpc_domain.key => vpc_domain }
device = each.value.device
admin_state = each.value.admin_state ? "enabled" : "disabled"

depends_on = [
nxos_feature_vpc.vpc
]
}

resource "nxos_vpc_domain" "vpc_domain" {
for_each = { for vpc_domain in local.vpc_domains : vpc_domain.key => vpc_domain }
device = each.value.device
domain_id = each.value.domain_id
admin_state = each.value.admin_state ? "enabled" : "disabled"
auto_recovery = each.value.auto_recovery ? "enabled" : "disabled"
auto_recovery_interval = each.value.auto_recovery_interval
delay_restore_orphan_port = each.value.delay_restore_orphan_port
delay_restore_svi = each.value.delay_restore_svi
delay_restore_vpc = each.value.delay_restore_vpc
dscp = each.value.dscp
fast_convergence = each.value.fast_convergence ? "enabled" : "disabled"
graceful_consistency_check = each.value.graceful_consistency_check ? "enabled" : "disabled"
l3_peer_router = each.value.l3_peer_router ? "enabled" : "disabled"
l3_peer_router_syslog = each.value.l3_peer_router_syslog ? "enabled" : "disabled"
l3_peer_router_syslog_interval = each.value.l3_peer_router_syslog_interval
peer_gateway = each.value.peer_gateway ? "enabled" : "disabled"
peer_ip = each.value.virtual_peerlink_destination_ip
peer_switch = each.value.peer_switch ? "enabled" : "disabled"
role_priority = each.value.role_priority
sys_mac = each.value.system_mac
system_priority = each.value.system_priority
track = each.value.track
virtual_ip = each.value.virtual_peerlink_source_ip

depends_on = [
nxos_vpc_instance.vpc_instance
]
}

locals {
vpc_keepalives = flatten([
for device in local.devices : [
{
key = format("%s/%s", device.name, local.device_config[device.name].vpc_domain.domain_id)
device = device.name
destination_ip = try(local.device_config[device.name].vpc_domain.peer_keepalive.destination_ip, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.destination_ip, null)
source_ip = try(local.device_config[device.name].vpc_domain.peer_keepalive.source_ip, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.source_ip, null)
flush_timeout = try(local.device_config[device.name].vpc_domain.peer_keepalive.flush_timeout, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.flush_timeout, null)
interval = try(local.device_config[device.name].vpc_domain.peer_keepalive.interval, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.interval, null)
precedence_type = try(local.device_config[device.name].vpc_domain.peer_keepalive.precedence_type, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.precedence_type, null)
precedence_value = try(local.device_config[device.name].vpc_domain.peer_keepalive.precedence_value, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.precedence_value, null)
timeout = try(local.device_config[device.name].vpc_domain.peer_keepalive.timeout, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.timeout, null)
type_of_service_byte = try(local.device_config[device.name].vpc_domain.peer_keepalive.type_of_service_byte, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.type_of_service_byte, null)
type_of_service_configuration_type = try(local.device_config[device.name].vpc_domain.peer_keepalive.type_of_service_configuration_type, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.type_of_service_configuration_type, null)
type_of_service_type = try(local.device_config[device.name].vpc_domain.peer_keepalive.type_of_service_type, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.type_of_service_type, null)
type_of_service_value = try(local.device_config[device.name].vpc_domain.peer_keepalive.type_of_service_value, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.type_of_service_value, null)
udp_port = try(local.device_config[device.name].vpc_domain.peer_keepalive.udp_port, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.udp_port, null)
vrf = try(local.device_config[device.name].vpc_domain.peer_keepalive.vrf, local.defaults.nxos.devices.configuration.vpc_domain.peer_keepalive.vrf, null)
}
] if try(local.device_config[device.name].vpc_domain, null) != null && try(local.device_config[device.name].vpc_domain.peer_keepalive, null) != null
])
}

resource "nxos_vpc_keepalive" "vpc_keepalive" {
for_each = { for vpc_keepalive in local.vpc_keepalives : vpc_keepalive.key => vpc_keepalive }
device = each.value.device
destination_ip = each.value.destination_ip
source_ip = each.value.source_ip
flush_timeout = each.value.flush_timeout
interval = each.value.interval
precedence_type = each.value.precedence_type
precedence_value = each.value.precedence_value
timeout = each.value.timeout
type_of_service_byte = each.value.type_of_service_byte
type_of_service_configuration_type = each.value.type_of_service_configuration_type
type_of_service_type = each.value.type_of_service_type
type_of_service_value = each.value.type_of_service_value
udp_port = each.value.udp_port
vrf = each.value.vrf

depends_on = [
nxos_vpc_domain.vpc_domain
]
}

locals {
vpc_peerlinks = flatten([
for device in local.devices : [
for int in try(local.device_config[device.name].interfaces.port_channels, []) : {
key = format("%s/%s", device.name, int.id)
device = device.name
port_channel_id = int.id
} if try(int.vpc_peerlink, false) == true
]
])
}

resource "nxos_vpc_peerlink" "vpc_peerlink" {
for_each = { for peerlink in local.vpc_peerlinks : peerlink.key => peerlink }
device = each.value.device
port_channel_id = format("po%s", each.value.port_channel_id)

depends_on = [
nxos_vpc_keepalive.vpc_keepalive
]
}

locals {
vpc_interfaces_port_channels = flatten([
for device in local.devices : [
for int in try(local.device_config[device.name].interfaces.port_channels, []) : {
key = format("%s/%s", device.name, int.id)
device = device.name
vpc_interface_id = int.vpc_id
port_channel_interface_dn = format("sys/intf/aggr-[po%s]", int.id)
} if try(int.vpc_id, null) != null && try(int.vpc_peerlink, false) == false
]
])
}

resource "nxos_vpc_interface" "vpc_interface" {
for_each = { for int in local.vpc_interfaces_port_channels : int.key => int }
device = each.value.device
vpc_interface_id = each.value.vpc_interface_id
port_channel_interface_dn = each.value.port_channel_interface_dn

depends_on = [
nxos_vpc_domain.vpc_domain,
nxos_port_channel_interface.port_channel_interface
]
}
2 changes: 1 addition & 1 deletion nxos_vrf.tf
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ resource "nxos_vrf_routing" "vrf_routing" {
}

resource "nxos_vrf_address_family" "vrf_address_family" {
for_each = { for v in local.vrfs_address_families : v.key => v }
for_each = { for v in local.vrfs_address_families : v.key => v if v.vrf != "default" }
device = each.value.device
vrf = nxos_vrf_routing.vrf_routing[each.value.vrf_key].vrf
address_family = each.value.address_family
Expand Down