From 8f633709471180e8116b6225a85994cbd0b481cc Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Sun, 13 Jul 2025 08:02:13 +0800 Subject: [PATCH 01/23] make interface group variables interpolation work --- main.tf | 15 +++++++++++++++ nxos_interface.tf | 8 ++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/main.tf b/main.tf index 5379da9..1cd9685 100644 --- a/main.tf +++ b/main.tf @@ -34,6 +34,21 @@ locals { )), "") } + interface_groups_raw_config = { + for device in local.devices : device.name => { + for ig in local.interface_groups : ig.name => yamlencode(try(ig.configuration, {})) + } + } + + interface_group_config = { + for device in local.devices : device.name => [ + for ig in local.interface_groups : { + name = ig.name + configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.device_variables[device.name])) + } + ] + } + device_variables = { for device in local.devices : device.name => merge(concat( [try(local.global.variables, {})], diff --git a/nxos_interface.tf b/nxos_interface.tf index c58a49a..4db8a7f 100644 --- a/nxos_interface.tf +++ b/nxos_interface.tf @@ -3,7 +3,7 @@ locals { for device in local.devices : [ for int in try(local.device_config[device.name].interfaces.ethernets, []) : { key = format("%s/%s", device.name, int.id) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) @@ -153,7 +153,7 @@ locals { 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) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) @@ -288,7 +288,7 @@ locals { for device in local.devices : [ for int in try(local.device_config[device.name].interfaces.loopbacks, []) : { key = format("%s/%s", device.name, int.id) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) @@ -397,7 +397,7 @@ locals { for device in local.devices : [ for int in try(local.device_config[device.name].interfaces.vlans, []) : { key = format("%s/%s", device.name, int.id) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) From 27741605b00a4aee0fddeb38a78beaf857035d3f Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Sun, 13 Jul 2025 08:10:09 +0800 Subject: [PATCH 02/23] make config template variables interpolation work with precedence: device-specific > configuration_template > device_group > global --- main.tf | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/main.tf b/main.tf index 5379da9..d62d759 100644 --- a/main.tf +++ b/main.tf @@ -6,21 +6,44 @@ locals { interface_groups = try(local.nxos.interface_groups, []) configuration_templates = try(local.nxos.configuration_templates, []) - device_group_config_template_variables = { for dg in local.device_groups : - dg.name => merge(concat( + device_variables = { for device in local.devices : + device.name => merge(concat( [try(local.global.variables, {})], - [try(dg.variables, {})], + [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], + [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], + [try(device.variables, {})] )...) } - device_group_config_template_raw_config = { for dg in local.device_groups : - dg.name => provider::utils::yaml_merge( - [for t in try(dg.configuration_templates, []) : yamlencode(try([for ct in local.configuration_templates : try(ct.configuration, {}) if ct.name == t][0], {}))] - ) + device_config_template_raw_config = { for device in local.devices : + device.name => provider::utils::yaml_merge([ + for dg in local.device_groups : + provider::utils::yaml_merge([ + for t in try(dg.configuration_templates, []) : + yamlencode(try([for ct in local.configuration_templates : try(ct.configuration, {}) if ct.name == t][0], {})) + ]) + if contains(try(device.device_groups, []), dg.name) || contains(try(dg.devices, []), device.name) + ]) + } + + device_config_template_variables = { for device in local.devices : + device.name => merge(concat( + [try(local.global.variables, {})], + [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], + [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], + [for dg in local.device_groups : + merge([ + for t in try(dg.configuration_templates, []) : + try([for ct in local.configuration_templates : try(ct.configuration.variables, {}) if ct.name == t][0], {}) + ]...) + if contains(try(device.device_groups, []), dg.name) || contains(try(dg.devices, []), device.name) + ], + [try(device.variables, {})] + )...) } - device_group_config_template_config = { for dg, config in local.device_group_config_template_raw_config : - dg => templatestring(config, local.device_group_config_template_variables[dg]) + device_config_template_config = { for device, config in local.device_config_template_raw_config : + device => templatestring(config, local.device_config_template_variables[device]) } raw_device_config = { for device in local.devices : @@ -34,15 +57,6 @@ locals { )), "") } - device_variables = { for device in local.devices : - device.name => merge(concat( - [try(local.global.variables, {})], - [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], - [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - [try(device.variables, {})] - )...) - } - device_config = { for device, config in local.raw_device_config : device => yamldecode(templatestring(config, local.device_variables[device])) } From 5210bdc0761b32d53a7c264cb53076748fa3285c Mon Sep 17 00:00:00 2001 From: haifwang <109054495+tobiwang@users.noreply.github.com> Date: Sun, 13 Jul 2025 09:40:59 +0900 Subject: [PATCH 03/23] fix variables interpolation for interface_groups and configuration_templates. variables interpolation precedence: device_specific > configuration_template > device_group > global --- main.tf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main.tf b/main.tf index d6e1bcd..fe0386f 100644 --- a/main.tf +++ b/main.tf @@ -51,8 +51,7 @@ locals { [yamlencode(try(local.global.configuration, {}))], [for dg in local.device_groups : yamlencode(try(dg.configuration, {})) if contains(try(device.device_groups, []), dg.name)], [for dg in local.device_groups : yamlencode(try(dg.configuration, {})) if contains(try(dg.devices, []), device.name)], - [for dg in local.device_groups : local.device_group_config_template_config[dg.name] if contains(try(device.device_groups, []), dg.name)], - [for dg in local.device_groups : local.device_group_config_template_config[dg.name] if contains(try(dg.devices, []), device.name)], + [local.device_config_template_config[device.name]], [yamlencode(try(device.configuration, {}))] )), "") } From 0943aeba4dd46df18057dde6a19b254119f02c06 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Mon, 14 Jul 2025 14:18:21 +0800 Subject: [PATCH 04/23] fix variables interpolation with precedence: device-level > interface_group-level > device_group-devel > global --- main.tf | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/main.tf b/main.tf index fe0386f..7d0f916 100644 --- a/main.tf +++ b/main.tf @@ -62,11 +62,23 @@ locals { } } + interface_group_variables = { + for device in local.devices : device.name => { + for ig in local.interface_groups : ig.name => merge(concat( + [try(local.global.variables, {})], + [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], + [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], + [try(ig.variables, {})], + [try(device.variables, {})] + )...) + } + } + interface_group_config = { for device in local.devices : device.name => [ for ig in local.interface_groups : { name = ig.name - configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.device_variables[device.name])) + configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.interface_group_variables[device.name][ig.name])) } ] } From ec7563eb5b81af68f1012951ebbe1e204f21fc08 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Tue, 15 Jul 2025 21:26:56 +0800 Subject: [PATCH 05/23] fix configuration_template variable interpolation --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index 7d0f916..7e84432 100644 --- a/main.tf +++ b/main.tf @@ -34,7 +34,7 @@ locals { [for dg in local.device_groups : merge([ for t in try(dg.configuration_templates, []) : - try([for ct in local.configuration_templates : try(ct.configuration.variables, {}) if ct.name == t][0], {}) + try([for ct in local.configuration_templates : try(ct.variables, {}) if ct.name == t][0], {}) ]...) if contains(try(device.device_groups, []), dg.name) || contains(try(dg.devices, []), device.name) ], From b4a52ba95281ea23957ba5632a36b8d08fe0c147 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Wed, 16 Jul 2025 10:11:06 +0800 Subject: [PATCH 06/23] Removing interface_group level variables support --- main.tf | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/main.tf b/main.tf index 7e84432..d77bba0 100644 --- a/main.tf +++ b/main.tf @@ -18,11 +18,11 @@ locals { device_config_template_raw_config = { for device in local.devices : device.name => provider::utils::yaml_merge([ for dg in local.device_groups : - provider::utils::yaml_merge([ - for t in try(dg.configuration_templates, []) : - yamlencode(try([for ct in local.configuration_templates : try(ct.configuration, {}) if ct.name == t][0], {})) - ]) - if contains(try(device.device_groups, []), dg.name) || contains(try(dg.devices, []), device.name) + provider::utils::yaml_merge([ + for t in try(dg.configuration_templates, []) : + yamlencode(try([for ct in local.configuration_templates : try(ct.configuration, {}) if ct.name == t][0], {})) + ]) + if contains(try(device.device_groups, []), dg.name) || contains(try(dg.devices, []), device.name) ]) } @@ -31,13 +31,6 @@ locals { [try(local.global.variables, {})], [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - [for dg in local.device_groups : - merge([ - for t in try(dg.configuration_templates, []) : - try([for ct in local.configuration_templates : try(ct.variables, {}) if ct.name == t][0], {}) - ]...) - if contains(try(device.device_groups, []), dg.name) || contains(try(dg.devices, []), device.name) - ], [try(device.variables, {})] )...) } @@ -68,7 +61,6 @@ locals { [try(local.global.variables, {})], [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - [try(ig.variables, {})], [try(device.variables, {})] )...) } @@ -77,7 +69,7 @@ locals { interface_group_config = { for device in local.devices : device.name => [ for ig in local.interface_groups : { - name = ig.name + name = ig.name configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.interface_group_variables[device.name][ig.name])) } ] From d7442197d877d7ddfe182019801187354f904951 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Wed, 16 Jul 2025 15:33:35 +0800 Subject: [PATCH 07/23] reuse device_variables --- main.tf | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/main.tf b/main.tf index d77bba0..5272e06 100644 --- a/main.tf +++ b/main.tf @@ -26,17 +26,17 @@ locals { ]) } - device_config_template_variables = { for device in local.devices : - device.name => merge(concat( - [try(local.global.variables, {})], - [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], - [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - [try(device.variables, {})] - )...) - } + # device_variables = { for device in local.devices : + # device.name => merge(concat( + # [try(local.global.variables, {})], + # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], + # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], + # [try(device.variables, {})] + # )...) + # } device_config_template_config = { for device, config in local.device_config_template_raw_config : - device => templatestring(config, local.device_config_template_variables[device]) + device => templatestring(config, local.device_variables[device]) } raw_device_config = { for device in local.devices : @@ -55,22 +55,22 @@ locals { } } - interface_group_variables = { - for device in local.devices : device.name => { - for ig in local.interface_groups : ig.name => merge(concat( - [try(local.global.variables, {})], - [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], - [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - [try(device.variables, {})] - )...) - } - } + # interface_group_variables = { + # for device in local.devices : device.name => { + # for ig in local.interface_groups : ig.name => merge(concat( + # [try(local.global.variables, {})], + # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], + # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], + # [try(device.variables, {})] + # )...) + # } + # } interface_group_config = { for device in local.devices : device.name => [ for ig in local.interface_groups : { name = ig.name - configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.interface_group_variables[device.name][ig.name])) + configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.device_variables[device.name][ig.name])) } ] } From 462d2d410b8d5b5157817882a32f111d87b03215 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Wed, 16 Jul 2025 16:03:52 +0800 Subject: [PATCH 08/23] fix interface_groups_config with re-using device_variables --- main.tf | 24 ++---------------------- nxos_interface.tf | 8 ++++---- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/main.tf b/main.tf index 5272e06..6a54597 100644 --- a/main.tf +++ b/main.tf @@ -26,15 +26,6 @@ locals { ]) } - # device_variables = { for device in local.devices : - # device.name => merge(concat( - # [try(local.global.variables, {})], - # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], - # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - # [try(device.variables, {})] - # )...) - # } - device_config_template_config = { for device, config in local.device_config_template_raw_config : device => templatestring(config, local.device_variables[device]) } @@ -55,22 +46,11 @@ locals { } } - # interface_group_variables = { - # for device in local.devices : device.name => { - # for ig in local.interface_groups : ig.name => merge(concat( - # [try(local.global.variables, {})], - # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], - # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - # [try(device.variables, {})] - # )...) - # } - # } - - interface_group_config = { + interface_groups_config = { for device in local.devices : device.name => [ for ig in local.interface_groups : { name = ig.name - configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.device_variables[device.name][ig.name])) + configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.device_variables[device.name])) } ] } diff --git a/nxos_interface.tf b/nxos_interface.tf index 4db8a7f..89f0844 100644 --- a/nxos_interface.tf +++ b/nxos_interface.tf @@ -3,7 +3,7 @@ locals { for device in local.devices : [ for int in try(local.device_config[device.name].interfaces.ethernets, []) : { key = format("%s/%s", device.name, int.id) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) @@ -153,7 +153,7 @@ locals { 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) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) @@ -288,7 +288,7 @@ locals { for device in local.devices : [ for int in try(local.device_config[device.name].interfaces.loopbacks, []) : { key = format("%s/%s", device.name, int.id) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) @@ -397,7 +397,7 @@ locals { for device in local.devices : [ for int in try(local.device_config[device.name].interfaces.vlans, []) : { key = format("%s/%s", device.name, int.id) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) From b02c5e54a5ba2536a051c791add956e48d306a22 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Wed, 16 Jul 2025 15:33:35 +0800 Subject: [PATCH 09/23] reuse device_variables --- main.tf | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/main.tf b/main.tf index d77bba0..5272e06 100644 --- a/main.tf +++ b/main.tf @@ -26,17 +26,17 @@ locals { ]) } - device_config_template_variables = { for device in local.devices : - device.name => merge(concat( - [try(local.global.variables, {})], - [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], - [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - [try(device.variables, {})] - )...) - } + # device_variables = { for device in local.devices : + # device.name => merge(concat( + # [try(local.global.variables, {})], + # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], + # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], + # [try(device.variables, {})] + # )...) + # } device_config_template_config = { for device, config in local.device_config_template_raw_config : - device => templatestring(config, local.device_config_template_variables[device]) + device => templatestring(config, local.device_variables[device]) } raw_device_config = { for device in local.devices : @@ -55,22 +55,22 @@ locals { } } - interface_group_variables = { - for device in local.devices : device.name => { - for ig in local.interface_groups : ig.name => merge(concat( - [try(local.global.variables, {})], - [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], - [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - [try(device.variables, {})] - )...) - } - } + # interface_group_variables = { + # for device in local.devices : device.name => { + # for ig in local.interface_groups : ig.name => merge(concat( + # [try(local.global.variables, {})], + # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], + # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], + # [try(device.variables, {})] + # )...) + # } + # } interface_group_config = { for device in local.devices : device.name => [ for ig in local.interface_groups : { name = ig.name - configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.interface_group_variables[device.name][ig.name])) + configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.device_variables[device.name][ig.name])) } ] } From 89b038150ed6d5c42c6cd438bec8d4f79eefaf48 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Wed, 16 Jul 2025 16:03:52 +0800 Subject: [PATCH 10/23] fix interface_groups_config with re-using device_variables --- main.tf | 24 ++---------------------- nxos_interface.tf | 8 ++++---- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/main.tf b/main.tf index 5272e06..6a54597 100644 --- a/main.tf +++ b/main.tf @@ -26,15 +26,6 @@ locals { ]) } - # device_variables = { for device in local.devices : - # device.name => merge(concat( - # [try(local.global.variables, {})], - # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], - # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - # [try(device.variables, {})] - # )...) - # } - device_config_template_config = { for device, config in local.device_config_template_raw_config : device => templatestring(config, local.device_variables[device]) } @@ -55,22 +46,11 @@ locals { } } - # interface_group_variables = { - # for device in local.devices : device.name => { - # for ig in local.interface_groups : ig.name => merge(concat( - # [try(local.global.variables, {})], - # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(device.device_groups, []), dg.name)], - # [for dg in local.device_groups : try(dg.variables, {}) if contains(try(dg.devices, []), device.name)], - # [try(device.variables, {})] - # )...) - # } - # } - - interface_group_config = { + interface_groups_config = { for device in local.devices : device.name => [ for ig in local.interface_groups : { name = ig.name - configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.device_variables[device.name][ig.name])) + configuration = yamldecode(templatestring(local.interface_groups_raw_config[device.name][ig.name], local.device_variables[device.name])) } ] } diff --git a/nxos_interface.tf b/nxos_interface.tf index 4db8a7f..89f0844 100644 --- a/nxos_interface.tf +++ b/nxos_interface.tf @@ -3,7 +3,7 @@ locals { for device in local.devices : [ for int in try(local.device_config[device.name].interfaces.ethernets, []) : { key = format("%s/%s", device.name, int.id) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) @@ -153,7 +153,7 @@ locals { 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) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) @@ -288,7 +288,7 @@ locals { for device in local.devices : [ for int in try(local.device_config[device.name].interfaces.loopbacks, []) : { key = format("%s/%s", device.name, int.id) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) @@ -397,7 +397,7 @@ locals { for device in local.devices : [ for int in try(local.device_config[device.name].interfaces.vlans, []) : { key = format("%s/%s", device.name, int.id) - configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_group_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) + configuration = yamldecode(provider::utils::yaml_merge([for g in try(int.interface_groups, []) : try([for ig in local.interface_groups_config[device.name] : yamlencode(ig.configuration) if ig.name == g][0], "")])) } ] ]) From 0008660498f26034c8a3e6674ad5da2c434be683 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Wed, 16 Jul 2025 16:25:44 +0800 Subject: [PATCH 11/23] fix variable names with using plural --- main.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main.tf b/main.tf index 6a54597..d3d827f 100644 --- a/main.tf +++ b/main.tf @@ -15,7 +15,7 @@ locals { )...) } - device_config_template_raw_config = { for device in local.devices : + device_config_templates_raw_config = { for device in local.devices : device.name => provider::utils::yaml_merge([ for dg in local.device_groups : provider::utils::yaml_merge([ @@ -26,16 +26,16 @@ locals { ]) } - device_config_template_config = { for device, config in local.device_config_template_raw_config : + device_config_templates_config = { for device, config in local.device_config_templates_raw_config : device => templatestring(config, local.device_variables[device]) } - raw_device_config = { for device in local.devices : + devices_raw_config = { for device in local.devices : device.name => try(provider::utils::yaml_merge(concat( [yamlencode(try(local.global.configuration, {}))], [for dg in local.device_groups : yamlencode(try(dg.configuration, {})) if contains(try(device.device_groups, []), dg.name)], [for dg in local.device_groups : yamlencode(try(dg.configuration, {})) if contains(try(dg.devices, []), device.name)], - [local.device_config_template_config[device.name]], + [local.device_config_templates_config[device.name]], [yamlencode(try(device.configuration, {}))] )), "") } @@ -55,7 +55,7 @@ locals { ] } - device_config = { for device, config in local.raw_device_config : + device_config = { for device, config in local.devices_raw_config : device => yamldecode(templatestring(config, local.device_variables[device])) } From 345c9661c6b22baf44f8b440a9730491ed79f0c9 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Tue, 29 Jul 2025 13:02:54 +0800 Subject: [PATCH 12/23] fix README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index d4b40d1..bd31daf 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,11 @@ module "nxos" { | [nxos_vrf_route_target_address_family.vrf_route_target_address_family](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vrf_route_target_address_family) | resource | | [nxos_vrf_route_target_direction.vrf_route_target_direction](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vrf_route_target_direction) | resource | | [nxos_vrf_routing.vrf_routing](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vrf_routing) | 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 | | [terraform_data.validation](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | ## Modules From bd1792e7fe0e88071020aa0a4ba60b17067cc725 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Tue, 29 Jul 2025 13:13:21 +0800 Subject: [PATCH 13/23] feat: Add comprehensive VPC (Virtual Port Channel) support - Add nxos_vpc_domain resource for VPC domain configuration - Add nxos_vpc_keepalive resource for VPC keepalive settings - Add nxos_vpc_peerlink resource for VPC peer-link configuration - Add nxos_vpc_interface resource for VPC member interfaces - Update main.tf to include VPC resources in dependencies - Add VPC defaults to defaults.yaml - Update README.md with VPC resource documentation - Add comprehensive VPC example with documentation This enables full VPC lifecycle management including: - VPC domain setup with role priority and system MAC - Keepalive configuration for failure detection - Peer-link configuration for synchronization - Member interface assignment with VPC IDs Supports both ethernet and port-channel interfaces as VPC members. --- README.md | 4 ++ defaults/defaults.yaml | 2 + main.tf | 6 +- nxos_ospf.tf | 2 +- nxos_vpc.tf | 141 +++++++++++++++++++++++++++++++++++++++++ nxos_vrf.tf | 2 +- 6 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 nxos_vpc.tf diff --git a/README.md b/README.md index bd31daf..ea8023b 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,10 @@ module "nxos" { | [nxos_feature_udld.udld](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/feature_udld) | resource | | [nxos_feature_vn_segment.vn_segment](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/feature_vn_segment) | resource | | [nxos_feature_vpc.vpc](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/feature_vpc) | resource | +| [nxos_vpc_domain.vpc_domain](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vpc_domain) | 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_vpc_interface.vpc_interface](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vpc_interface) | resource | | [nxos_hmm.hmm](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/hmm) | resource | | [nxos_hmm_instance.hmm_instance](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/hmm_instance) | resource | | [nxos_hmm_interface.hmm_interface](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/hmm_interface) | resource | diff --git a/defaults/defaults.yaml b/defaults/defaults.yaml index 6e6d834..3167b06 100644 --- a/defaults/defaults.yaml +++ b/defaults/defaults.yaml @@ -38,3 +38,5 @@ defaults: additive: false no_community: false set_criteria: none + vpc_domains: + admin_state: true \ No newline at end of file diff --git a/main.tf b/main.tf index d3d827f..4890234 100644 --- a/main.tf +++ b/main.tf @@ -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 ] } diff --git a/nxos_ospf.tf b/nxos_ospf.tf index 96d1f09..6317133 100644 --- a/nxos_ospf.tf +++ b/nxos_ospf.tf @@ -95,7 +95,7 @@ resource "nxos_ospf_area" "ospf_area" { } locals { - ospf_interfaces = concat(local.interfaces_ethernets, local.interfaces_loopbacks, local.interfaces_vlans, local.interfaces_port_channels) + ospf_interfaces = concat(local.interfaces_ethernets, local.interfaces_loopbacks, local.interfaces_vlans) } resource "nxos_ospf_interface" "ospf_interface" { diff --git a/nxos_vpc.tf b/nxos_vpc.tf new file mode 100644 index 0000000..e15924d --- /dev/null +++ b/nxos_vpc.tf @@ -0,0 +1,141 @@ +locals { + vpc_domains = flatten([ + for device in local.devices : [ + try(local.device_config[device.name].vpc_domain, null) != null ? { + 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_domains.domain_id, null) + admin_state = try(local.device_config[device.name].vpc_domain.admin_state, local.defaults.nxos.devices.configuration.vpc_domains.admin_state, true) + auto_recovery = try(local.device_config[device.name].vpc_domain.auto_recovery, local.defaults.nxos.devices.configuration.vpc_domains.auto_recovery, false) + auto_recovery_interval = try(local.device_config[device.name].vpc_domain.auto_recovery_interval, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.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_domains.delay_restore_svi, null) + delay_restore_vpc = try(local.device_config[device.name].vpc_domain.delay_restore_vpc, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_vpc, null) + dscp = try(local.device_config[device.name].vpc_domain.dscp, local.defaults.nxos.devices.configuration.vpc_domains.dscp, null) + fast_convergence = try(local.device_config[device.name].vpc_domain.fast_convergence, local.defaults.nxos.devices.configuration.vpc_domains.fast_convergence, false) + graceful_consistency_check = try(local.device_config[device.name].vpc_domain.graceful_consistency_check, local.defaults.nxos.devices.configuration.vpc_domains.graceful_consistency_check, false) + l3_peer_router = try(local.device_config[device.name].vpc_domain.l3_peer_router, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.l3_peer_router_syslog, false) + l3_peer_router_syslog_interval = try(local.device_config[device.name].vpc_domain.l3_peer_router_syslog_interval, local.defaults.nxos.devices.configuration.vpc_domains.l3_peer_router_syslog_interval, null) + peer_gateway = try(local.device_config[device.name].vpc_domain.peer_gateway, local.defaults.nxos.devices.configuration.vpc_domains.peer_gateway, false) + peer_ip = try(local.device_config[device.name].vpc_domain.peer_ip, local.defaults.nxos.devices.configuration.vpc_domains.peer_ip, null) + peer_switch = try(local.device_config[device.name].vpc_domain.peer_switch, local.defaults.nxos.devices.configuration.vpc_domains.peer_switch, false) + role_priority = try(local.device_config[device.name].vpc_domain.role_priority, local.defaults.nxos.devices.configuration.vpc_domains.role_priority, null) + system_mac = try(upper(local.device_config[device.name].vpc_domain.system_mac), upper(local.defaults.nxos.devices.configuration.vpc_domains.system_mac), null) + system_priority = try(local.device_config[device.name].vpc_domain.system_priority, local.defaults.nxos.devices.configuration.vpc_domains.system_priority, null) + track = try(local.device_config[device.name].vpc_domain.track, local.defaults.nxos.devices.configuration.vpc_domains.track, null) + virtual_ip = try(local.device_config[device.name].vpc_domain.virtual_ip, local.defaults.nxos.devices.configuration.vpc_domains.virtual_ip, null) + peer_keepalive = try(local.device_config[device.name].vpc_domain.peer_keepalive, {}) + } : null + ] 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 = try(each.value.admin_state, local.defaults.nxos.devices.configuration.vpc_domains.admin_state, true) ? "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 = try(each.value.admin_state, local.defaults.nxos.devices.configuration.vpc_domains.admin_state, true) ? "enabled" : "disabled" + auto_recovery = try(each.value.auto_recovery, local.defaults.nxos.devices.configuration.vpc_domains.auto_recovery, false) ? "enabled" : "disabled" + auto_recovery_interval = try(each.value.auto_recovery_interval, local.defaults.nxos.devices.configuration.vpc_domains.auto_recovery_interval, null) + delay_restore_orphan_port = try(each.value.delay_restore_orphan_port, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_orphan_port, null) + delay_restore_svi = try(each.value.delay_restore_svi, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_svi, null) + delay_restore_vpc = try(each.value.delay_restore_vpc, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_vpc, null) + dscp = try(each.value.dscp, local.defaults.nxos.devices.configuration.vpc_domains.dscp, null) + fast_convergence = try(each.value.fast_convergence, local.defaults.nxos.devices.configuration.vpc_domains.fast_convergence, false) ? "enabled" : "disabled" + graceful_consistency_check = try(each.value.graceful_consistency_check, local.defaults.nxos.devices.configuration.vpc_domains.graceful_consistency_check, false) ? "enabled" : "disabled" + l3_peer_router = try(each.value.l3_peer_router, local.defaults.nxos.devices.configuration.vpc_domains.l3_peer_router, false) ? "enabled" : "disabled" + l3_peer_router_syslog = try(each.value.l3_peer_router_syslog, local.defaults.nxos.devices.configuration.vpc_domains.l3_peer_router_syslog, false) ? "enabled" : "disabled" + l3_peer_router_syslog_interval = try(each.value.l3_peer_router_syslog_interval, local.defaults.nxos.devices.configuration.vpc_domains.l3_peer_router_syslog_interval, null) + peer_gateway = try(each.value.peer_gateway, local.defaults.nxos.devices.configuration.vpc_domains.peer_gateway, false) ? "enabled" : "disabled" + peer_ip = try(each.value.peer_ip, local.defaults.nxos.devices.configuration.vpc_domains.peer_ip, null) + peer_switch = try(each.value.peer_switch, local.defaults.nxos.devices.configuration.vpc_domains.peer_switch, false) ? "enabled" : "disabled" + role_priority = try(each.value.role_priority, local.defaults.nxos.devices.configuration.vpc_domains.role_priority, null) + sys_mac = try(each.value.system_mac, local.defaults.nxos.devices.configuration.vpc_domains.system_mac, null) + system_priority = try(each.value.system_priority, local.defaults.nxos.devices.configuration.vpc_domains.system_priority, null) + track = try(each.value.track, local.defaults.nxos.devices.configuration.vpc_domains.track, null) + virtual_ip = try(each.value.virtual_ip, local.defaults.nxos.devices.configuration.vpc_domains.virtual_ip, null) + + depends_on = [ + nxos_vpc_instance.vpc_instance + ] +} + +resource "nxos_vpc_keepalive" "vpc_keepalive" { + for_each = { for vpc_domain in local.vpc_domains : vpc_domain.key => vpc_domain } + device = each.value.device + destination_ip = try(each.value.peer_keepalive.destination_ip, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.destination_ip, null) + source_ip = try(each.value.peer_keepalive.source_ip, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.source_ip, null) + flush_timeout = try(each.value.peer_keepalive.flush_timeout, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.flush_timeout, null) + interval = try(each.value.peer_keepalive.interval, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.interval, null) + precedence_type = try(each.value.peer_keepalive.precedence_type, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.precedence_type, null) + precedence_value = try(each.value.peer_keepalive.precedence_value, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.precedence_value, null) + timeout = try(each.value.peer_keepalive.timeout, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.timeout, null) + type_of_service_byte = try(each.value.peer_keepalive.type_of_service_byte, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.type_of_service_byte, null) + type_of_service_configuration_type = try(each.value.peer_keepalive.type_of_service_configuration_type, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.type_of_service_configuration_type, null) + type_of_service_type = try(each.value.peer_keepalive.type_of_service_type, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.type_of_service_type, null) + type_of_service_value = try(each.value.peer_keepalive.type_of_service_value, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.type_of_service_value, null) + udp_port = try(each.value.peer_keepalive.udp_port, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.udp_port, null) + vrf = try(each.value.peer_keepalive.vrf, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.vrf, null) + + 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 + ] +} diff --git a/nxos_vrf.tf b/nxos_vrf.tf index bd645ad..3861a2b 100644 --- a/nxos_vrf.tf +++ b/nxos_vrf.tf @@ -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 From bb15c1abf01dcfcbd6479a4b1f1b6e75290607c2 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Tue, 29 Jul 2025 14:05:40 +0800 Subject: [PATCH 14/23] fix interface_port_channel ospf --- README.md | 4 ---- nxos_ospf.tf | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ea8023b..bd31daf 100644 --- a/README.md +++ b/README.md @@ -106,10 +106,6 @@ module "nxos" { | [nxos_feature_udld.udld](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/feature_udld) | resource | | [nxos_feature_vn_segment.vn_segment](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/feature_vn_segment) | resource | | [nxos_feature_vpc.vpc](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/feature_vpc) | resource | -| [nxos_vpc_domain.vpc_domain](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vpc_domain) | 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_vpc_interface.vpc_interface](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vpc_interface) | resource | | [nxos_hmm.hmm](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/hmm) | resource | | [nxos_hmm_instance.hmm_instance](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/hmm_instance) | resource | | [nxos_hmm_interface.hmm_interface](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/hmm_interface) | resource | diff --git a/nxos_ospf.tf b/nxos_ospf.tf index 6317133..d741a0b 100644 --- a/nxos_ospf.tf +++ b/nxos_ospf.tf @@ -95,11 +95,11 @@ resource "nxos_ospf_area" "ospf_area" { } locals { - ospf_interfaces = concat(local.interfaces_ethernets, local.interfaces_loopbacks, local.interfaces_vlans) + ospf_interfaces = concat(local.interfaces_ethernets, local.interfaces_loopbacks, local.interfaces_vlans, local.interfaces_port_channels) } 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 From 26b6214ff3aebd4b1c034d3f41aef715e283c371 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Tue, 29 Jul 2025 14:12:20 +0800 Subject: [PATCH 15/23] fix interface_port_channel ospf --- nxos_ospf.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nxos_ospf.tf b/nxos_ospf.tf index d741a0b..7d9c02d 100644 --- a/nxos_ospf.tf +++ b/nxos_ospf.tf @@ -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 From 24668e09e60b5fca749ab4ae69be8d6ef67a9ef2 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Tue, 29 Jul 2025 16:07:02 +0800 Subject: [PATCH 16/23] fix virtual peerlink --- VPC_IMPLEMENTATION.md | 0 nxos_vpc.tf | 116 +++++++++++++++++++++--------------------- 2 files changed, 58 insertions(+), 58 deletions(-) create mode 100644 VPC_IMPLEMENTATION.md diff --git a/VPC_IMPLEMENTATION.md b/VPC_IMPLEMENTATION.md new file mode 100644 index 0000000..e69de29 diff --git a/nxos_vpc.tf b/nxos_vpc.tf index e15924d..4b80adf 100644 --- a/nxos_vpc.tf +++ b/nxos_vpc.tf @@ -2,30 +2,30 @@ locals { vpc_domains = flatten([ for device in local.devices : [ try(local.device_config[device.name].vpc_domain, null) != null ? { - 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_domains.domain_id, null) - admin_state = try(local.device_config[device.name].vpc_domain.admin_state, local.defaults.nxos.devices.configuration.vpc_domains.admin_state, true) - auto_recovery = try(local.device_config[device.name].vpc_domain.auto_recovery, local.defaults.nxos.devices.configuration.vpc_domains.auto_recovery, false) - auto_recovery_interval = try(local.device_config[device.name].vpc_domain.auto_recovery_interval, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.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_domains.delay_restore_svi, null) - delay_restore_vpc = try(local.device_config[device.name].vpc_domain.delay_restore_vpc, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_vpc, null) - dscp = try(local.device_config[device.name].vpc_domain.dscp, local.defaults.nxos.devices.configuration.vpc_domains.dscp, null) - fast_convergence = try(local.device_config[device.name].vpc_domain.fast_convergence, local.defaults.nxos.devices.configuration.vpc_domains.fast_convergence, false) - graceful_consistency_check = try(local.device_config[device.name].vpc_domain.graceful_consistency_check, local.defaults.nxos.devices.configuration.vpc_domains.graceful_consistency_check, false) - l3_peer_router = try(local.device_config[device.name].vpc_domain.l3_peer_router, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.l3_peer_router_syslog, false) - l3_peer_router_syslog_interval = try(local.device_config[device.name].vpc_domain.l3_peer_router_syslog_interval, local.defaults.nxos.devices.configuration.vpc_domains.l3_peer_router_syslog_interval, null) - peer_gateway = try(local.device_config[device.name].vpc_domain.peer_gateway, local.defaults.nxos.devices.configuration.vpc_domains.peer_gateway, false) - peer_ip = try(local.device_config[device.name].vpc_domain.peer_ip, local.defaults.nxos.devices.configuration.vpc_domains.peer_ip, null) - peer_switch = try(local.device_config[device.name].vpc_domain.peer_switch, local.defaults.nxos.devices.configuration.vpc_domains.peer_switch, false) - role_priority = try(local.device_config[device.name].vpc_domain.role_priority, local.defaults.nxos.devices.configuration.vpc_domains.role_priority, null) - system_mac = try(upper(local.device_config[device.name].vpc_domain.system_mac), upper(local.defaults.nxos.devices.configuration.vpc_domains.system_mac), null) - system_priority = try(local.device_config[device.name].vpc_domain.system_priority, local.defaults.nxos.devices.configuration.vpc_domains.system_priority, null) - track = try(local.device_config[device.name].vpc_domain.track, local.defaults.nxos.devices.configuration.vpc_domains.track, null) - virtual_ip = try(local.device_config[device.name].vpc_domain.virtual_ip, local.defaults.nxos.devices.configuration.vpc_domains.virtual_ip, null) - peer_keepalive = try(local.device_config[device.name].vpc_domain.peer_keepalive, {}) + 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_domains.domain_id, null) + admin_state = try(local.device_config[device.name].vpc_domain.admin_state, local.defaults.nxos.devices.configuration.vpc_domains.admin_state, true) + auto_recovery = try(local.device_config[device.name].vpc_domain.auto_recovery, local.defaults.nxos.devices.configuration.vpc_domains.auto_recovery, false) + auto_recovery_interval = try(local.device_config[device.name].vpc_domain.auto_recovery_interval, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.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_domains.delay_restore_svi, null) + delay_restore_vpc = try(local.device_config[device.name].vpc_domain.delay_restore_vpc, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_vpc, null) + dscp = try(local.device_config[device.name].vpc_domain.dscp, local.defaults.nxos.devices.configuration.vpc_domains.dscp, null) + fast_convergence = try(local.device_config[device.name].vpc_domain.fast_convergence, local.defaults.nxos.devices.configuration.vpc_domains.fast_convergence, false) + graceful_consistency_check = try(local.device_config[device.name].vpc_domain.graceful_consistency_check, local.defaults.nxos.devices.configuration.vpc_domains.graceful_consistency_check, false) + l3_peer_router = try(local.device_config[device.name].vpc_domain.l3_peer_router, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.l3_peer_router_syslog, false) + l3_peer_router_syslog_interval = try(local.device_config[device.name].vpc_domain.l3_peer_router_syslog_interval, local.defaults.nxos.devices.configuration.vpc_domains.l3_peer_router_syslog_interval, null) + peer_gateway = try(local.device_config[device.name].vpc_domain.peer_gateway, local.defaults.nxos.devices.configuration.vpc_domains.peer_gateway, false) + virtual_peerlink_destination_ip = try(local.device_config[device.name].vpc_domain.virtual_peerlink_destination_ip, local.defaults.nxos.devices.configuration.vpc_domains.virtual_peerlink_destination_ip, null) + peer_switch = try(local.device_config[device.name].vpc_domain.peer_switch, local.defaults.nxos.devices.configuration.vpc_domains.peer_switch, false) + role_priority = try(local.device_config[device.name].vpc_domain.role_priority, local.defaults.nxos.devices.configuration.vpc_domains.role_priority, null) + system_mac = try(upper(local.device_config[device.name].vpc_domain.system_mac), upper(local.defaults.nxos.devices.configuration.vpc_domains.system_mac), null) + system_priority = try(local.device_config[device.name].vpc_domain.system_priority, local.defaults.nxos.devices.configuration.vpc_domains.system_priority, null) + track = try(local.device_config[device.name].vpc_domain.track, local.defaults.nxos.devices.configuration.vpc_domains.track, null) + virtual_peerlink_source_ip = try(local.device_config[device.name].vpc_domain.virtual_peerlink_source_ip, local.defaults.nxos.devices.configuration.vpc_domains.virtual_peerlink_source_ip, null) + peer_keepalive = try(local.device_config[device.name].vpc_domain.peer_keepalive, {}) } : null ] if try(local.device_config[device.name].vpc_domain, null) != null ]) @@ -34,7 +34,7 @@ locals { 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 = try(each.value.admin_state, local.defaults.nxos.devices.configuration.vpc_domains.admin_state, true) ? "enabled" : "disabled" + admin_state = each.value.admin_state ? "enabled" : "disabled" depends_on = [ nxos_feature_vpc.vpc @@ -45,26 +45,26 @@ 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 = try(each.value.admin_state, local.defaults.nxos.devices.configuration.vpc_domains.admin_state, true) ? "enabled" : "disabled" - auto_recovery = try(each.value.auto_recovery, local.defaults.nxos.devices.configuration.vpc_domains.auto_recovery, false) ? "enabled" : "disabled" - auto_recovery_interval = try(each.value.auto_recovery_interval, local.defaults.nxos.devices.configuration.vpc_domains.auto_recovery_interval, null) - delay_restore_orphan_port = try(each.value.delay_restore_orphan_port, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_orphan_port, null) - delay_restore_svi = try(each.value.delay_restore_svi, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_svi, null) - delay_restore_vpc = try(each.value.delay_restore_vpc, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_vpc, null) - dscp = try(each.value.dscp, local.defaults.nxos.devices.configuration.vpc_domains.dscp, null) - fast_convergence = try(each.value.fast_convergence, local.defaults.nxos.devices.configuration.vpc_domains.fast_convergence, false) ? "enabled" : "disabled" - graceful_consistency_check = try(each.value.graceful_consistency_check, local.defaults.nxos.devices.configuration.vpc_domains.graceful_consistency_check, false) ? "enabled" : "disabled" - l3_peer_router = try(each.value.l3_peer_router, local.defaults.nxos.devices.configuration.vpc_domains.l3_peer_router, false) ? "enabled" : "disabled" - l3_peer_router_syslog = try(each.value.l3_peer_router_syslog, local.defaults.nxos.devices.configuration.vpc_domains.l3_peer_router_syslog, false) ? "enabled" : "disabled" - l3_peer_router_syslog_interval = try(each.value.l3_peer_router_syslog_interval, local.defaults.nxos.devices.configuration.vpc_domains.l3_peer_router_syslog_interval, null) - peer_gateway = try(each.value.peer_gateway, local.defaults.nxos.devices.configuration.vpc_domains.peer_gateway, false) ? "enabled" : "disabled" - peer_ip = try(each.value.peer_ip, local.defaults.nxos.devices.configuration.vpc_domains.peer_ip, null) - peer_switch = try(each.value.peer_switch, local.defaults.nxos.devices.configuration.vpc_domains.peer_switch, false) ? "enabled" : "disabled" - role_priority = try(each.value.role_priority, local.defaults.nxos.devices.configuration.vpc_domains.role_priority, null) - sys_mac = try(each.value.system_mac, local.defaults.nxos.devices.configuration.vpc_domains.system_mac, null) - system_priority = try(each.value.system_priority, local.defaults.nxos.devices.configuration.vpc_domains.system_priority, null) - track = try(each.value.track, local.defaults.nxos.devices.configuration.vpc_domains.track, null) - virtual_ip = try(each.value.virtual_ip, local.defaults.nxos.devices.configuration.vpc_domains.virtual_ip, null) + 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 @@ -74,19 +74,19 @@ resource "nxos_vpc_domain" "vpc_domain" { resource "nxos_vpc_keepalive" "vpc_keepalive" { for_each = { for vpc_domain in local.vpc_domains : vpc_domain.key => vpc_domain } device = each.value.device - destination_ip = try(each.value.peer_keepalive.destination_ip, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.destination_ip, null) - source_ip = try(each.value.peer_keepalive.source_ip, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.source_ip, null) - flush_timeout = try(each.value.peer_keepalive.flush_timeout, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.flush_timeout, null) - interval = try(each.value.peer_keepalive.interval, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.interval, null) - precedence_type = try(each.value.peer_keepalive.precedence_type, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.precedence_type, null) - precedence_value = try(each.value.peer_keepalive.precedence_value, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.precedence_value, null) - timeout = try(each.value.peer_keepalive.timeout, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.timeout, null) - type_of_service_byte = try(each.value.peer_keepalive.type_of_service_byte, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.type_of_service_byte, null) - type_of_service_configuration_type = try(each.value.peer_keepalive.type_of_service_configuration_type, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.type_of_service_configuration_type, null) - type_of_service_type = try(each.value.peer_keepalive.type_of_service_type, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.type_of_service_type, null) - type_of_service_value = try(each.value.peer_keepalive.type_of_service_value, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.type_of_service_value, null) - udp_port = try(each.value.peer_keepalive.udp_port, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.udp_port, null) - vrf = try(each.value.peer_keepalive.vrf, local.defaults.nxos.devices.configuration.vpc_domains.keepalives.vrf, null) + destination_ip = each.value.peer_keepalive.destination_ip + source_ip = each.value.peer_keepalive.source_ip + flush_timeout = each.value.peer_keepalive.flush_timeout + interval = each.value.peer_keepalive.interval + precedence_type = each.value.peer_keepalive.precedence_type + precedence_value = each.value.peer_keepalive.precedence_value + timeout = each.value.peer_keepalive.timeout + type_of_service_byte = each.value.peer_keepalive.type_of_service_byte + type_of_service_configuration_type = each.value.peer_keepalive.type_of_service_configuration_type + type_of_service_type = each.value.peer_keepalive.type_of_service_type + type_of_service_value = each.value.peer_keepalive.type_of_service_value + udp_port = each.value.peer_keepalive.udp_port + vrf = each.value.peer_keepalive.vrf depends_on = [ nxos_vpc_domain.vpc_domain From 74fb5f52cb86a6720d7700cc139b38a40e83a778 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Tue, 29 Jul 2025 16:25:30 +0800 Subject: [PATCH 17/23] fix --- nxos_vpc.tf | 54 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/nxos_vpc.tf b/nxos_vpc.tf index 4b80adf..d94f82e 100644 --- a/nxos_vpc.tf +++ b/nxos_vpc.tf @@ -27,7 +27,7 @@ locals { virtual_peerlink_source_ip = try(local.device_config[device.name].vpc_domain.virtual_peerlink_source_ip, local.defaults.nxos.devices.configuration.vpc_domains.virtual_peerlink_source_ip, null) peer_keepalive = try(local.device_config[device.name].vpc_domain.peer_keepalive, {}) } : null - ] if try(local.device_config[device.name].vpc_domain, null) != null + ] ]) } @@ -71,22 +71,46 @@ resource "nxos_vpc_domain" "vpc_domain" { ] } +locals { + vpc_keepalives = flatten([ + for device in local.devices : [ + try(local.device_config[device.name].vpc_domain, null) != null && try(local.device_config[device.name].vpc_domain.peer_keepalive, null) != null ? { + 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_domains.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_domains.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_domains.peer_keepalive.flush_timeout, null) + interval = try(local.device_config[device.name].vpc_domain.peer_keepalive.interval, local.defaults.nxos.devices.configuration.vpc_domains.peer_keepalive.interval, null) + precedence_type = try(local.device_config[device.name].vpc_domain.peer_keepalive.precedence_type, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.peer_keepalive.precedence_value, null) + timeout = try(local.device_config[device.name].vpc_domain.peer_keepalive.timeout, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.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_domains.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_domains.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_domains.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_domains.peer_keepalive.udp_port, null) + vrf = try(local.device_config[device.name].vpc_domain.peer_keepalive.vrf, local.defaults.nxos.devices.configuration.vpc_domains.peer_keepalive.vrf, null) + } : null + ] + ]) +} + resource "nxos_vpc_keepalive" "vpc_keepalive" { - for_each = { for vpc_domain in local.vpc_domains : vpc_domain.key => vpc_domain } + for_each = { for vpc_keepalive in local.vpc_keepalives : vpc_keepalive.key => vpc_keepalive } device = each.value.device - destination_ip = each.value.peer_keepalive.destination_ip - source_ip = each.value.peer_keepalive.source_ip - flush_timeout = each.value.peer_keepalive.flush_timeout - interval = each.value.peer_keepalive.interval - precedence_type = each.value.peer_keepalive.precedence_type - precedence_value = each.value.peer_keepalive.precedence_value - timeout = each.value.peer_keepalive.timeout - type_of_service_byte = each.value.peer_keepalive.type_of_service_byte - type_of_service_configuration_type = each.value.peer_keepalive.type_of_service_configuration_type - type_of_service_type = each.value.peer_keepalive.type_of_service_type - type_of_service_value = each.value.peer_keepalive.type_of_service_value - udp_port = each.value.peer_keepalive.udp_port - vrf = each.value.peer_keepalive.vrf + 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 From 0391603adc0c9ad5f854c9878e804eb8bd3ba915 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Tue, 29 Jul 2025 16:33:08 +0800 Subject: [PATCH 18/23] fix --- nxos_vpc.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nxos_vpc.tf b/nxos_vpc.tf index d94f82e..c5d81bd 100644 --- a/nxos_vpc.tf +++ b/nxos_vpc.tf @@ -1,7 +1,7 @@ locals { vpc_domains = flatten([ for device in local.devices : [ - try(local.device_config[device.name].vpc_domain, null) != null ? { + { 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_domains.domain_id, null) @@ -26,8 +26,8 @@ locals { track = try(local.device_config[device.name].vpc_domain.track, local.defaults.nxos.devices.configuration.vpc_domains.track, null) virtual_peerlink_source_ip = try(local.device_config[device.name].vpc_domain.virtual_peerlink_source_ip, local.defaults.nxos.devices.configuration.vpc_domains.virtual_peerlink_source_ip, null) peer_keepalive = try(local.device_config[device.name].vpc_domain.peer_keepalive, {}) - } : null - ] + } + ] if try(local.device_config[device.name].vpc_domain, null) != null ]) } @@ -74,7 +74,7 @@ resource "nxos_vpc_domain" "vpc_domain" { locals { vpc_keepalives = flatten([ for device in local.devices : [ - try(local.device_config[device.name].vpc_domain, null) != null && try(local.device_config[device.name].vpc_domain.peer_keepalive, null) != null ? { + { 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_domains.peer_keepalive.destination_ip, null) @@ -90,8 +90,8 @@ locals { type_of_service_value = try(local.device_config[device.name].vpc_domain.peer_keepalive.type_of_service_value, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.peer_keepalive.udp_port, null) vrf = try(local.device_config[device.name].vpc_domain.peer_keepalive.vrf, local.defaults.nxos.devices.configuration.vpc_domains.peer_keepalive.vrf, null) - } : null - ] + } + ] if try(local.device_config[device.name].vpc_domain, null) != null && try(local.device_config[device.name].vpc_domain.peer_keepalive, null) != null ]) } From 1ad641284f13b7a6ffc6ee78e24c7a1dcce461b5 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Tue, 29 Jul 2025 17:28:59 +0800 Subject: [PATCH 19/23] fix yamllint error issue of defaults.yaml --- VPC_IMPLEMENTATION.md | 0 defaults/defaults.yaml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 VPC_IMPLEMENTATION.md diff --git a/VPC_IMPLEMENTATION.md b/VPC_IMPLEMENTATION.md deleted file mode 100644 index e69de29..0000000 diff --git a/defaults/defaults.yaml b/defaults/defaults.yaml index 3167b06..af21d6b 100644 --- a/defaults/defaults.yaml +++ b/defaults/defaults.yaml @@ -39,4 +39,4 @@ defaults: no_community: false set_criteria: none vpc_domains: - admin_state: true \ No newline at end of file + admin_state: true From c36b3e7881eef8259054371c67fd429662b68971 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Tue, 29 Jul 2025 17:34:45 +0800 Subject: [PATCH 20/23] re-order vpc related resources --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bd31daf..447afa1 100644 --- a/README.md +++ b/README.md @@ -161,17 +161,17 @@ 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 | | [nxos_vrf_route_target_address_family.vrf_route_target_address_family](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vrf_route_target_address_family) | resource | | [nxos_vrf_route_target_direction.vrf_route_target_direction](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vrf_route_target_direction) | resource | | [nxos_vrf_routing.vrf_routing](https://registry.terraform.io/providers/CiscoDevNet/nxos/latest/docs/resources/vrf_routing) | 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 | | [terraform_data.validation](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | ## Modules From d7c839d01c074992617327fb2437df0f48b0da8a Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Wed, 30 Jul 2025 20:47:56 +0800 Subject: [PATCH 21/23] using null (omit) as a last resort instead of hardcording --- nxos_vpc.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/nxos_vpc.tf b/nxos_vpc.tf index c5d81bd..d47676d 100644 --- a/nxos_vpc.tf +++ b/nxos_vpc.tf @@ -5,21 +5,21 @@ locals { 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_domains.domain_id, null) - admin_state = try(local.device_config[device.name].vpc_domain.admin_state, local.defaults.nxos.devices.configuration.vpc_domains.admin_state, true) - auto_recovery = try(local.device_config[device.name].vpc_domain.auto_recovery, local.defaults.nxos.devices.configuration.vpc_domains.auto_recovery, false) + admin_state = try(local.device_config[device.name].vpc_domain.admin_state, local.defaults.nxos.devices.configuration.vpc_domains.admin_state, null) + auto_recovery = try(local.device_config[device.name].vpc_domain.auto_recovery, local.defaults.nxos.devices.configuration.vpc_domains.auto_recovery, null) auto_recovery_interval = try(local.device_config[device.name].vpc_domain.auto_recovery_interval, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.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_domains.delay_restore_svi, null) delay_restore_vpc = try(local.device_config[device.name].vpc_domain.delay_restore_vpc, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_vpc, null) dscp = try(local.device_config[device.name].vpc_domain.dscp, local.defaults.nxos.devices.configuration.vpc_domains.dscp, null) - fast_convergence = try(local.device_config[device.name].vpc_domain.fast_convergence, local.defaults.nxos.devices.configuration.vpc_domains.fast_convergence, false) - graceful_consistency_check = try(local.device_config[device.name].vpc_domain.graceful_consistency_check, local.defaults.nxos.devices.configuration.vpc_domains.graceful_consistency_check, false) + fast_convergence = try(local.device_config[device.name].vpc_domain.fast_convergence, local.defaults.nxos.devices.configuration.vpc_domains.fast_convergence, null) + graceful_consistency_check = try(local.device_config[device.name].vpc_domain.graceful_consistency_check, local.defaults.nxos.devices.configuration.vpc_domains.graceful_consistency_check, null) l3_peer_router = try(local.device_config[device.name].vpc_domain.l3_peer_router, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.l3_peer_router_syslog, false) + l3_peer_router_syslog = try(local.device_config[device.name].vpc_domain.l3_peer_router_syslog, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.l3_peer_router_syslog_interval, null) - peer_gateway = try(local.device_config[device.name].vpc_domain.peer_gateway, local.defaults.nxos.devices.configuration.vpc_domains.peer_gateway, false) + peer_gateway = try(local.device_config[device.name].vpc_domain.peer_gateway, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.virtual_peerlink_destination_ip, null) - peer_switch = try(local.device_config[device.name].vpc_domain.peer_switch, local.defaults.nxos.devices.configuration.vpc_domains.peer_switch, false) + peer_switch = try(local.device_config[device.name].vpc_domain.peer_switch, local.defaults.nxos.devices.configuration.vpc_domains.peer_switch, null) role_priority = try(local.device_config[device.name].vpc_domain.role_priority, local.defaults.nxos.devices.configuration.vpc_domains.role_priority, null) system_mac = try(upper(local.device_config[device.name].vpc_domain.system_mac), upper(local.defaults.nxos.devices.configuration.vpc_domains.system_mac), null) system_priority = try(local.device_config[device.name].vpc_domain.system_priority, local.defaults.nxos.devices.configuration.vpc_domains.system_priority, null) From 9e7f4aace7da3f1a8ff231bec9ec66464c07f808 Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Wed, 30 Jul 2025 20:52:25 +0800 Subject: [PATCH 22/23] vpc_domain in defaults.yaml --- defaults/defaults.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults/defaults.yaml b/defaults/defaults.yaml index af21d6b..22c6200 100644 --- a/defaults/defaults.yaml +++ b/defaults/defaults.yaml @@ -38,5 +38,5 @@ defaults: additive: false no_community: false set_criteria: none - vpc_domains: + vpc_domain: admin_state: true From 7418dc5f0c82165d4a6b51f9c7bf067585bf75ef Mon Sep 17 00:00:00 2001 From: "Tobi Wang (haifwang)" Date: Fri, 1 Aug 2025 11:34:28 +0800 Subject: [PATCH 23/23] fix defaults value reference --- nxos_vpc.tf | 68 ++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/nxos_vpc.tf b/nxos_vpc.tf index d47676d..91cb307 100644 --- a/nxos_vpc.tf +++ b/nxos_vpc.tf @@ -4,27 +4,27 @@ locals { { 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_domains.domain_id, null) - admin_state = try(local.device_config[device.name].vpc_domain.admin_state, local.defaults.nxos.devices.configuration.vpc_domains.admin_state, null) - auto_recovery = try(local.device_config[device.name].vpc_domain.auto_recovery, local.defaults.nxos.devices.configuration.vpc_domains.auto_recovery, null) - auto_recovery_interval = try(local.device_config[device.name].vpc_domain.auto_recovery_interval, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.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_domains.delay_restore_svi, null) - delay_restore_vpc = try(local.device_config[device.name].vpc_domain.delay_restore_vpc, local.defaults.nxos.devices.configuration.vpc_domains.delay_restore_vpc, null) - dscp = try(local.device_config[device.name].vpc_domain.dscp, local.defaults.nxos.devices.configuration.vpc_domains.dscp, null) - fast_convergence = try(local.device_config[device.name].vpc_domain.fast_convergence, local.defaults.nxos.devices.configuration.vpc_domains.fast_convergence, null) - graceful_consistency_check = try(local.device_config[device.name].vpc_domain.graceful_consistency_check, local.defaults.nxos.devices.configuration.vpc_domains.graceful_consistency_check, null) - l3_peer_router = try(local.device_config[device.name].vpc_domain.l3_peer_router, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.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_domains.l3_peer_router_syslog_interval, null) - peer_gateway = try(local.device_config[device.name].vpc_domain.peer_gateway, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.virtual_peerlink_destination_ip, null) - peer_switch = try(local.device_config[device.name].vpc_domain.peer_switch, local.defaults.nxos.devices.configuration.vpc_domains.peer_switch, null) - role_priority = try(local.device_config[device.name].vpc_domain.role_priority, local.defaults.nxos.devices.configuration.vpc_domains.role_priority, null) - system_mac = try(upper(local.device_config[device.name].vpc_domain.system_mac), upper(local.defaults.nxos.devices.configuration.vpc_domains.system_mac), null) - system_priority = try(local.device_config[device.name].vpc_domain.system_priority, local.defaults.nxos.devices.configuration.vpc_domains.system_priority, null) - track = try(local.device_config[device.name].vpc_domain.track, local.defaults.nxos.devices.configuration.vpc_domains.track, null) - virtual_peerlink_source_ip = try(local.device_config[device.name].vpc_domain.virtual_peerlink_source_ip, local.defaults.nxos.devices.configuration.vpc_domains.virtual_peerlink_source_ip, null) + 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 @@ -77,19 +77,19 @@ locals { { 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_domains.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_domains.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_domains.peer_keepalive.flush_timeout, null) - interval = try(local.device_config[device.name].vpc_domain.peer_keepalive.interval, local.defaults.nxos.devices.configuration.vpc_domains.peer_keepalive.interval, null) - precedence_type = try(local.device_config[device.name].vpc_domain.peer_keepalive.precedence_type, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.peer_keepalive.precedence_value, null) - timeout = try(local.device_config[device.name].vpc_domain.peer_keepalive.timeout, local.defaults.nxos.devices.configuration.vpc_domains.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_domains.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_domains.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_domains.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_domains.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_domains.peer_keepalive.udp_port, null) - vrf = try(local.device_config[device.name].vpc_domain.peer_keepalive.vrf, local.defaults.nxos.devices.configuration.vpc_domains.peer_keepalive.vrf, null) + 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 ])