From 27b6ef28111e6046d3ab0c48ca0f6698f46d2b4d Mon Sep 17 00:00:00 2001 From: lab Date: Fri, 17 May 2024 16:12:11 +0200 Subject: [PATCH] add l3out svi encap scope --- aci_tenants.tf | 4 ++++ defaults/defaults.yaml | 2 ++ modules/terraform-aci-l3out-interface-profile/README.md | 3 ++- .../examples/complete/README.md | 1 + .../examples/complete/main.tf | 1 + modules/terraform-aci-l3out-interface-profile/main.tf | 6 ++++-- .../terraform-aci-l3out-interface-profile/variables.tf | 8 ++++++++ 7 files changed, 22 insertions(+), 3 deletions(-) diff --git a/aci_tenants.tf b/aci_tenants.tf index 1f6de6dc..de74ecb1 100644 --- a/aci_tenants.tf +++ b/aci_tenants.tf @@ -983,6 +983,7 @@ locals { ip_a = try(int.ip_a, null) ip_b = try(int.ip_b, null) ip_shared = try(int.ip_shared, null) + scope = try(int.scope, local.defaults.apic.tenants.l3outs.node_profiles.interface_profiles.interfaces.scope) multipod_direct = tenant.name == "infra" ? try(int.multipod_direct, false) : false bgp_peers = [for peer in try(int.bgp_peers, []) : { ip = peer.ip @@ -1071,6 +1072,7 @@ module "aci_l3out_interface_profile_manual" { ip_shared = int.ip_shared bgp_peers = int.bgp_peers paths = int.paths + scope = int.scope multipod_direct = int.multipod_direct }] @@ -1124,6 +1126,7 @@ locals { ip_a = try(int.ip_a, null) ip_b = try(int.ip_b, null) ip_shared = try(int.ip_shared, null) + scope = try(int.scope, local.defaults.apic.tenants.l3outs.node_profiles.interface_profiles.interfaces.scope) multipod_direct = tenant.name == "infra" ? try(int.multipod_direct, false) : false bgp_peers = [for peer in try(int.bgp_peers, []) : { ip = peer.ip @@ -1210,6 +1213,7 @@ module "aci_l3out_interface_profile_auto" { ip_shared = int.ip_shared bgp_peers = int.bgp_peers paths = int.paths + scope = int.scope multipod_direct = int.multipod_direct }] diff --git a/defaults/defaults.yaml b/defaults/defaults.yaml index 7a3ff1a2..ff35eba3 100644 --- a/defaults/defaults.yaml +++ b/defaults/defaults.yaml @@ -802,6 +802,7 @@ defaults: mac: 00:22:BD:F8:19:FF mtu: inherit mode: regular + scope: local bgp_peers: allow_self_as: false as_override: false @@ -869,6 +870,7 @@ defaults: mac: 00:22:BD:F8:19:FF mtu: inherit mode: regular + scope: local bgp_peers: allow_self_as: false as_override: false diff --git a/modules/terraform-aci-l3out-interface-profile/README.md b/modules/terraform-aci-l3out-interface-profile/README.md index 77e38d4f..dbcba8e3 100644 --- a/modules/terraform-aci-l3out-interface-profile/README.md +++ b/modules/terraform-aci-l3out-interface-profile/README.md @@ -32,6 +32,7 @@ module "aci_l3out_interface_profile" { description = "Interface 1" type = "vpc" svi = true + scope = "local" vlan = 5 mac = "12:34:56:78:90:AB" mtu = "1500" @@ -109,7 +110,7 @@ module "aci_l3out_interface_profile" { | [igmp\_interface\_policy](#input\_igmp\_interface\_policy) | IGMP interface policy name. | `string` | `""` | no | | [qos\_class](#input\_qos\_class) | QoS class. Choices: `level1`, `level2`, `level3`, `level4`, `level5`, `level6`, `unspecified`. | `string` | `"unspecified"` | no | | [custom\_qos\_policy](#input\_custom\_qos\_policy) | Custom QoS policy name. | `string` | `""` | no | -| [interfaces](#input\_interfaces) | List of interfaces. Default value `svi`: false. Default value `floating_svi`: false. Choices `type`. `access`, `pc`, `vpc`. Default value `type`: `access`. Allowed values `vlan`: 1-4096. Format `mac`: `12:34:56:78:9A:BC`. `mtu`: Allowed values are `inherit` or a number between 576 and 9216. Allowed values `node_id`, `node2_id`: 1-4000. Allowed values `pod_id`: 1-255. Default value `pod_id`: 1. Allowed values `module`: 1-9. Default value `module`: 1. Allowed values `port`: 1-127. Default value `bgp_peers.bfd`: false. Allowed values `bgp_peers.ttl`: 1-255. Default value `bgp_peers.ttl`: 1. Allowed values `bgp_peers.weight`: 0-65535. Default value `bgp_peers.weight`: 0. Allowed values `bgp_peers.remote_as`: 0-4294967295. |
list(object({
description = optional(string, "")
type = optional(string, "access")
node_id = number
node2_id = optional(number)
pod_id = optional(number, 1)
module = optional(number, 1)
port = optional(number)
channel = optional(string)
ip = optional(string)
svi = optional(bool, false)
autostate = optional(bool, false)
floating_svi = optional(bool, false)
vlan = optional(number)
mac = optional(string, "00:22:BD:F8:19:FF")
mtu = optional(string, "inherit")
mode = optional(string, "regular")
ip_a = optional(string)
ip_b = optional(string)
ip_shared = optional(string)
multipod_direct = optional(bool, false)
bgp_peers = optional(list(object({
ip = string
remote_as = string
description = optional(string, "")
allow_self_as = optional(bool, false)
as_override = optional(bool, false)
disable_peer_as_check = optional(bool, false)
next_hop_self = optional(bool, false)
send_community = optional(bool, false)
send_ext_community = optional(bool, false)
password = optional(string)
allowed_self_as_count = optional(number, 3)
bfd = optional(bool, false)
disable_connected_check = optional(bool, false)
ttl = optional(number, 1)
weight = optional(number, 0)
remove_all_private_as = optional(bool, false)
remove_private_as = optional(bool, false)
replace_private_as_with_local_as = optional(bool, false)
unicast_address_family = optional(bool, true)
multicast_address_family = optional(bool, true)
admin_state = optional(bool, true)
local_as = optional(number)
as_propagate = optional(string, "none")
peer_prefix_policy = optional(string)
export_route_control = optional(string)
import_route_control = optional(string)
})), [])
paths = optional(list(object({
physical_domain = optional(string)
vmware_vmm_domain = optional(string)
elag = optional(string)
floating_ip = string
})), [])
}))
| `[]` | no | +| [interfaces](#input\_interfaces) | List of interfaces. Default value `svi`: false. Default value `floating_svi`: false. Choices `type`. `access`, `pc`, `vpc`. Default value `type`: `access`. Allowed values `vlan`: 1-4096. Format `mac`: `12:34:56:78:9A:BC`. `mtu`: Allowed values are `inherit` or a number between 576 and 9216. Allowed values `node_id`, `node2_id`: 1-4000. Allowed values `pod_id`: 1-255. Default value `pod_id`: 1. Allowed values `module`: 1-9. Default value `module`: 1. Allowed values `port`: 1-127. Default value `bgp_peers.bfd`: false. Allowed values `bgp_peers.ttl`: 1-255. Default value `bgp_peers.ttl`: 1. Allowed values `bgp_peers.weight`: 0-65535. Default value `bgp_peers.weight`: 0. Allowed values `bgp_peers.remote_as`: 0-4294967295. |
list(object({
description = optional(string, "")
type = optional(string, "access")
node_id = number
node2_id = optional(number)
pod_id = optional(number, 1)
module = optional(number, 1)
port = optional(number)
channel = optional(string)
ip = optional(string)
svi = optional(bool, false)
autostate = optional(bool, false)
floating_svi = optional(bool, false)
vlan = optional(number)
mac = optional(string, "00:22:BD:F8:19:FF")
mtu = optional(string, "inherit")
mode = optional(string, "regular")
ip_a = optional(string)
ip_b = optional(string)
ip_shared = optional(string)
scope = optional(string, "local")
multipod_direct = optional(bool, false)
bgp_peers = optional(list(object({
ip = string
remote_as = string
description = optional(string, "")
allow_self_as = optional(bool, false)
as_override = optional(bool, false)
disable_peer_as_check = optional(bool, false)
next_hop_self = optional(bool, false)
send_community = optional(bool, false)
send_ext_community = optional(bool, false)
password = optional(string)
allowed_self_as_count = optional(number, 3)
bfd = optional(bool, false)
disable_connected_check = optional(bool, false)
ttl = optional(number, 1)
weight = optional(number, 0)
remove_all_private_as = optional(bool, false)
remove_private_as = optional(bool, false)
replace_private_as_with_local_as = optional(bool, false)
unicast_address_family = optional(bool, true)
multicast_address_family = optional(bool, true)
admin_state = optional(bool, true)
local_as = optional(number)
as_propagate = optional(string, "none")
peer_prefix_policy = optional(string)
export_route_control = optional(string)
import_route_control = optional(string)
})), [])
paths = optional(list(object({
physical_domain = optional(string)
vmware_vmm_domain = optional(string)
elag = optional(string)
floating_ip = string
})), [])
}))
| `[]` | no | | [multipod](#input\_multipod) | Multipod L3out flag. | `bool` | `false` | no | | [remote\_leaf](#input\_remote\_leaf) | Remote leaf L3out flag. | `bool` | `false` | no | | [sr\_mpls](#input\_sr\_mpls) | SR MPLS L3out flag. | `bool` | `false` | no | diff --git a/modules/terraform-aci-l3out-interface-profile/examples/complete/README.md b/modules/terraform-aci-l3out-interface-profile/examples/complete/README.md index d9185c88..0fbf05b3 100644 --- a/modules/terraform-aci-l3out-interface-profile/examples/complete/README.md +++ b/modules/terraform-aci-l3out-interface-profile/examples/complete/README.md @@ -35,6 +35,7 @@ module "aci_l3out_interface_profile" { description = "Interface 1" type = "vpc" svi = true + scope = "local" vlan = 5 mac = "12:34:56:78:90:AB" mtu = "1500" diff --git a/modules/terraform-aci-l3out-interface-profile/examples/complete/main.tf b/modules/terraform-aci-l3out-interface-profile/examples/complete/main.tf index 885d8c53..6a8aacad 100644 --- a/modules/terraform-aci-l3out-interface-profile/examples/complete/main.tf +++ b/modules/terraform-aci-l3out-interface-profile/examples/complete/main.tf @@ -21,6 +21,7 @@ module "aci_l3out_interface_profile" { description = "Interface 1" type = "vpc" svi = true + scope = "local" vlan = 5 mac = "12:34:56:78:90:AB" mtu = "1500" diff --git a/modules/terraform-aci-l3out-interface-profile/main.tf b/modules/terraform-aci-l3out-interface-profile/main.tf index 16f2a093..473f85bc 100644 --- a/modules/terraform-aci-l3out-interface-profile/main.tf +++ b/modules/terraform-aci-l3out-interface-profile/main.tf @@ -23,6 +23,7 @@ locals { ip_shared = int.ip_shared tDn = int.type == "vpc" ? "topology/pod-${int.pod_id}/protpaths-${int.node_id}-${int.node2_id}/pathep-[${int.channel}]" : (int.type == "pc" ? "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[${int.channel}]" : "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[eth${int.module}/${int.port}]") multipod_direct = int.multipod_direct + scope = int.scope } } if int.floating_svi == false ]) @@ -76,6 +77,7 @@ locals { mtu = int.mtu node_id = int.node_id pod_id = int.pod_id + scope = int.scope } } if int.floating_svi == true ]) @@ -263,7 +265,6 @@ resource "aci_rest_managed" "l3extRsPathL3OutAtt" { content = { addr = each.value.ip descr = each.value.description - encapScope = "local" ifInstT = each.value.vlan != null ? (each.value.svi == "yes" ? "ext-svi" : "sub-interface") : "l3-port" autostate = each.value.autostate encap = each.value.vlan != null ? "vlan-${each.value.vlan}" : null @@ -274,6 +275,7 @@ resource "aci_rest_managed" "l3extRsPathL3OutAtt" { mtu = each.value.mtu tDn = each.value.tDn isMultiPodDirect = each.value.multipod_direct ? "yes" : null + encapScope = each.value.svi == "yes" ? each.value.scope == "vrf" ? "ctx" : "local" : null } } @@ -332,7 +334,6 @@ resource "aci_rest_managed" "l3extVirtualLIfP" { addr = each.value.ip autostate = each.value.autostate descr = each.value.description - encapScope = "local" ifInstT = "ext-svi" encap = "vlan-${each.value.vlan}" ipv6Dad = "enabled" @@ -341,6 +342,7 @@ resource "aci_rest_managed" "l3extVirtualLIfP" { mode = each.value.mode mtu = each.value.mtu nodeDn = "topology/pod-${each.value.pod_id}/node-${each.value.node_id}" + encapScope = each.value.scope == "vrf" ? "ctx" : "local" } } diff --git a/modules/terraform-aci-l3out-interface-profile/variables.tf b/modules/terraform-aci-l3out-interface-profile/variables.tf index 4a4335e0..621e2438 100644 --- a/modules/terraform-aci-l3out-interface-profile/variables.tf +++ b/modules/terraform-aci-l3out-interface-profile/variables.tf @@ -199,6 +199,7 @@ variable "interfaces" { ip_a = optional(string) ip_b = optional(string) ip_shared = optional(string) + scope = optional(string, "local") multipod_direct = optional(bool, false) bgp_peers = optional(list(object({ ip = string @@ -321,6 +322,13 @@ variable "interfaces" { error_message = "`channel`: Allowed characters: `a`-`z`, `A`-`Z`, `0`-`9`, `_`, `.`, `-`, `:`. Maximum characters: 64." } + validation { + condition = alltrue([ + for i in var.interfaces : i.scope == null || try(contains(["local", "vrf"], i.scope), false) + ]) + error_message = "`scope`: Allowed values are `local` or `vrf`" + } + validation { condition = alltrue(flatten([ for i in var.interfaces : [for b in coalesce(i.bgp_peers, []) : b.remote_as >= 0 && b.remote_as <= 4294967295]