diff --git a/aci_tenants.tf b/aci_tenants.tf index aab90d9a..33cd83d4 100644 --- a/aci_tenants.tf +++ b/aci_tenants.tf @@ -1060,7 +1060,28 @@ locals { peer_prefix_policy = try("${peer.peer_prefix_policy}${local.defaults.apic.tenants.policies.bgp_peer_prefix_policies.name_suffix}", null) export_route_control = try("${peer.export_route_control}${local.defaults.apic.tenants.policies.route_control_route_maps.name_suffix}", null) import_route_control = try("${peer.import_route_control}${local.defaults.apic.tenants.policies.route_control_route_maps.name_suffix}", null) - }] + } if tenant.name != "infra"] + bgp_infra_peers = [for peer in try(np.bgp_infra_peers, []) : { + ip = peer.ip + remote_as = peer.remote_as + admin_state = try(peer.admin_state, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.admin_state) + description = try(peer.description, "") + allow_self_as = try(peer.allow_self_as, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.allow_self_as) + disable_peer_as_check = try(peer.disable_peer_as_check, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.disable_peer_as_check) + as_override = try(peer.as_override, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.as_override) + next_hop_self = try(peer.next_hop_self, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.next_hop_self) + send_community = try(peer.send_community, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.send_community) + send_ext_community = try(peer.send_ext_community, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.send_ext_community) + peer_type = try(peer.peer_type, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.peer_type) + bfd = try(peer.bfd, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.bfd) + password = try(peer.password, null) + ttl = try(peer.ttl, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.ttl) + local_as = try(peer.local_as, null) + as_propagate = try(peer.as_propagate, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.as_propagate) + source_interface_type = try(peer.peer_type, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.peer_type) == "wan" ? try(peer.source_interface_type, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.source_interface_type) : null + data_plane_address = try(peer.peer_type, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.peer_type) == "wan" && try(peer.source_interface_type, local.defaults.apic.tenants.l3outs.node_profiles.bgp_infra_peers.source_interface_type) == "routable-loopback" ? try(peer.data_plane_address, null) : null + peer_prefix_policy = try("${peer.peer_prefix_policy}${local.defaults.apic.tenants.policies.bgp_peer_prefix_policies.name_suffix}", null) + } if tenant.name == "infra"] } ] ] @@ -1081,6 +1102,7 @@ module "aci_l3out_node_profile_manual" { bgp_as_path_policy = each.value.bgp_as_path_policy nodes = each.value.nodes bgp_peers = each.value.bgp_peers + bgp_infra_peers = each.value.bgp_infra_peers bfd_multihop_node_policy = each.value.bfd_multihop_node_policy bfd_multihop_auth_key_id = each.value.bfd_multihop_auth_key_id bfd_multihop_auth_key = each.value.bfd_multihop_auth_key @@ -1159,7 +1181,28 @@ locals { peer_prefix_policy = try("${peer.peer_prefix_policy}${local.defaults.apic.tenants.policies.bgp_peer_prefix_policies.name_suffix}", null) export_route_control = try("${peer.export_route_control}${local.defaults.apic.tenants.policies.route_control_route_maps.name_suffix}", null) import_route_control = try("${peer.import_route_control}${local.defaults.apic.tenants.policies.route_control_route_maps.name_suffix}", null) - }] + } if tenant.name != "infra"] + bgp_infra_peers = [for peer in try(l3out.bgp_infra_peers, []) : { + ip = peer.ip + remote_as = peer.remote_as + admin_state = try(peer.admin_state, local.defaults.apic.tenants.l3outs.bgp_infra_peers.admin_state) + description = try(peer.description, "") + allow_self_as = try(peer.allow_self_as, local.defaults.apic.tenants.l3outs.bgp_infra_peers.allow_self_as) + disable_peer_as_check = try(peer.disable_peer_as_check, local.defaults.apic.tenants.l3outs.bgp_infra_peers.disable_peer_as_check) + as_override = try(peer.as_override, local.defaults.apic.tenants.l3outs.bgp_infra_peers.as_override) + next_hop_self = try(peer.next_hop_self, local.defaults.apic.tenants.l3outs.bgp_infra_peers.next_hop_self) + send_community = try(peer.send_community, local.defaults.apic.tenants.l3outs.bgp_infra_peers.send_community) + send_ext_community = try(peer.send_ext_community, local.defaults.apic.tenants.l3outs.bgp_infra_peers.send_ext_community) + peer_type = try(peer.peer_type, local.defaults.apic.tenants.l3outs.bgp_infra_peers.peer_type) + bfd = try(peer.bfd, local.defaults.apic.tenants.l3outs.bgp_infra_peers.bfd) + password = try(peer.password, null) + ttl = try(peer.ttl, local.defaults.apic.tenants.l3outs.bgp_infra_peers.ttl) + local_as = try(peer.local_as, null) + as_propagate = try(peer.as_propagate, local.defaults.apic.tenants.l3outs.bgp_infra_peers.as_propagate) + source_interface_type = try(peer.peer_type, local.defaults.apic.tenants.l3outs.bgp_infra_peers.peer_type) == "wan" ? try(peer.source_interface_type, local.defaults.apic.tenants.l3outs.bgp_infra_peers.source_interface_type) : null + data_plane_address = try(peer.peer_type, local.defaults.apic.tenants.l3outs.bgp_infra_peers.peer_type) == "wan" && try(peer.source_interface_type, local.defaults.apic.tenants.l3outs.bgp_infra_peers.source_interface_type) == "routable-loopback" ? try(peer.data_plane_address, null) : null + peer_prefix_policy = try("${peer.peer_prefix_policy}${local.defaults.apic.tenants.policies.bgp_peer_prefix_policies.name_suffix}", null) + } if tenant.name == "infra"] } if length(try(l3out.nodes, [])) != 0 ] ]) @@ -1179,6 +1222,7 @@ module "aci_l3out_node_profile_auto" { bgp_as_path_policy = each.value.bgp_as_path_policy nodes = each.value.nodes bgp_peers = each.value.bgp_peers + bgp_infra_peers = each.value.bgp_infra_peers bfd_multihop_node_policy = each.value.bfd_multihop_node_policy bfd_multihop_auth_key_id = each.value.bfd_multihop_auth_key_id bfd_multihop_auth_key = each.value.bfd_multihop_auth_key @@ -1706,6 +1750,9 @@ locals { local_as = try(peer.local_as, null) as_propagate = try(peer.as_propagate, local.defaults.apic.tenants.sr_mpls_l3outs.node_profiles.evpn_connectivity.as_propagate) peer_prefix_policy = try("${peer.peer_prefix_policy}${local.defaults.apic.tenants.policies.bgp_peer_prefix_policies.name_suffix}", null) + peer_type = "sr-mpls" + send_community = true + send_ext_community = true }] } ] diff --git a/defaults/defaults.yaml b/defaults/defaults.yaml index 8252d9b9..c32a15cd 100644 --- a/defaults/defaults.yaml +++ b/defaults/defaults.yaml @@ -952,6 +952,20 @@ defaults: multicast_address_family: true admin_state: true as_propagate: none + bgp_infra_peers: + name_suffix: "" + peer_type: wan + allow_self_as: false + disable_peer_as_check: false + send_community: false + send_ext_community: false + next_hop_self: false + as_override: false + ttl: 2 + bfd: false + admin_state: true + as_propagate: none + source_interface_type: l3out-loopback redistribution_route_maps: source: static dhcp_labels: @@ -1026,6 +1040,20 @@ defaults: multicast_address_family: true admin_state: true as_propagate: none + bgp_infra_peers: + name_suffix: "" + peer_type: wan + allow_self_as: false + disable_peer_as_check: false + send_community: false + send_ext_community: false + next_hop_self: false + as_override: false + ttl: 2 + bfd: false + admin_state: true + as_propagate: none + source_interface_type: l3out-loopback nodes: pod: 1 router_id_as_loopback: true diff --git a/modules/terraform-aci-l3out-node-profile/README.md b/modules/terraform-aci-l3out-node-profile/README.md index e50f247e..971f91d4 100644 --- a/modules/terraform-aci-l3out-node-profile/README.md +++ b/modules/terraform-aci-l3out-node-profile/README.md @@ -104,7 +104,7 @@ module "aci_l3out_node_profile" { | [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 | -| [bgp\_infra\_peers](#input\_bgp\_infra\_peers) | List of BGP EVPN peers for SR MPLS L3out. Allowed values `remote_as`: 0-4294967295. Default value `allow_self_as`: false. Default value `disable_peer_as_check`: false. Default value `bfd`: false. Default value `ttl`: 2. Default value `admin_state`: true. Allowed values `local_as`: 0-4294967295. Choices `as_propagate`: `none`, `no-prepend`, `replace-as`, `dual-as`. Default value `as_propagate`: `none`. |
list(object({
ip = string
remote_as = string
description = optional(string, "")
allow_self_as = optional(bool, false)
disable_peer_as_check = optional(bool, false)
password = optional(string)
bfd = optional(bool, false)
ttl = optional(number, 1)
admin_state = optional(bool, true)
local_as = optional(number)
as_propagate = optional(string, "none")
peer_prefix_policy = optional(string)
})) | `[]` | no |
+| [bgp\_infra\_peers](#input\_bgp\_infra\_peers) | List of BGP peers for Infra L3out. Allowed values `remote_as`: 0-4294967295. Default value `allow_self_as`: false. Default value `disable_peer_as_check`: false. Default value `bfd`: false. Default value `ttl`: 2. Default value `admin_state`: true. Allowed values `local_as`: 0-4294967295. Choices `as_propagate`: `none`, `no-prepend`, `replace-as`, `dual-as`. Default value `as_propagate`: `none`. Choices `peer_type`: `sr-mpls`, `wan`, `mdp-wan` or `intersite` | list(object({
ip = string
remote_as = string
description = optional(string, "")
allow_self_as = optional(bool, false)
disable_peer_as_check = optional(bool, false)
as_override = optional(bool, false)
next_hop_self = optional(bool, false)
send_community = optional(bool, false)
send_ext_community = optional(bool, false)
password = optional(string)
bfd = optional(bool, false)
ttl = optional(number, 1)
admin_state = optional(bool, true)
local_as = optional(number)
as_propagate = optional(string, "none")
peer_prefix_policy = optional(string)
peer_type = optional(string)
source_interface_type = optional(string, "l3out-loopback")
data_plane_address = optional(string, null)
})) | `[]` | no |
| [mpls\_custom\_qos\_policy](#input\_mpls\_custom\_qos\_policy) | MPLS Customer QoS Policy | `string` | `""` | no |
| [bfd\_multihop\_node\_policy](#input\_bfd\_multihop\_node\_policy) | BFD Multihop Node Policy | `string` | `""` | no |
| [bgp\_protocol\_profile\_name](#input\_bgp\_protocol\_profile\_name) | BGP Protocol Name. | `string` | `""` | no |
diff --git a/modules/terraform-aci-l3out-node-profile/main.tf b/modules/terraform-aci-l3out-node-profile/main.tf
index f385f17f..958037ac 100644
--- a/modules/terraform-aci-l3out-node-profile/main.tf
+++ b/modules/terraform-aci-l3out-node-profile/main.tf
@@ -231,28 +231,30 @@ resource "aci_rest_managed" "bfdRsMhNodePol" {
}
resource "aci_rest_managed" "bgpInfraPeerP" {
- for_each = { for peer in var.bgp_infra_peers : peer.ip => peer }
+ for_each = { for peer in var.bgp_infra_peers : peer.ip => peer if var.sr_mpls == true || (var.sr_mpls == false && peer.peer_type != "sr-mpls" && peer.peer_type != "vxlan-bgw") }
dn = "${aci_rest_managed.l3extLNodeP.dn}/infraPeerP-[${each.value.ip}]"
class_name = "bgpInfraPeerP"
escape_html = false
content = {
- addr = each.value.ip
- descr = each.value.description
- ctrl = join(",", concat(each.value.allow_self_as == true ? ["allow-self-as"] : [], each.value.disable_peer_as_check == true ? ["dis-peer-as-check"] : [], ["send-com"], ["send-ext-com"]))
- password = sensitive(each.value.password)
- peerCtrl = join(",", concat(each.value.bfd == true ? ["bfd"] : []))
- peerT = "sr-mpls"
- ttl = each.value.ttl
- adminSt = each.value.admin_state == true ? "enabled" : "disabled"
+ addr = each.value.ip
+ descr = each.value.description
+ ctrl = join(",", concat(each.value.allow_self_as == true ? ["allow-self-as"] : [], each.value.as_override == true ? ["as-override"] : [], each.value.disable_peer_as_check == true ? ["dis-peer-as-check"] : [], each.value.next_hop_self == true ? ["nh-self"] : [], each.value.send_community == true ? ["send-com"] : [], each.value.send_ext_community == true ? ["send-ext-com"] : []))
+ password = sensitive(each.value.password)
+ peerCtrl = join(",", concat(each.value.bfd == true ? ["bfd"] : []))
+ peerT = each.value.peer_type
+ ttl = each.value.ttl
+ adminSt = each.value.admin_state == true ? "enabled" : "disabled"
+ srcIfT = each.value.source_interface_type
+ dataPlaneAddr = each.value.data_plane_address
}
lifecycle {
- ignore_changes = [content["password"]]
+ ignore_changes = [content["password"], content["srcIfT"], content["peerT"]]
}
}
resource "aci_rest_managed" "bgpAsP-bgpInfraPeerP" {
- for_each = { for peer in var.bgp_infra_peers : peer.ip => peer }
+ for_each = { for peer in var.bgp_infra_peers : peer.ip => peer if var.sr_mpls || (var.sr_mpls == false && peer.peer_type != "sr-mpls" && peer.peer_type != "vxlan-bgw") }
dn = "${aci_rest_managed.bgpInfraPeerP[each.key].dn}/as"
class_name = "bgpAsP"
content = {
@@ -261,7 +263,7 @@ resource "aci_rest_managed" "bgpAsP-bgpInfraPeerP" {
}
resource "aci_rest_managed" "bgpLocalAsnP-bgpInfraPeerP" {
- for_each = { for peer in var.bgp_infra_peers : peer.ip => peer if peer.local_as != null }
+ for_each = { for peer in var.bgp_infra_peers : peer.ip => peer if(var.sr_mpls || (var.sr_mpls == false && peer.peer_type != "sr-mpls" && peer.peer_type != "vxlan-bgw")) && peer.local_as != null }
dn = "${aci_rest_managed.bgpInfraPeerP[each.key].dn}/localasn"
class_name = "bgpLocalAsnP"
content = {
@@ -271,7 +273,7 @@ resource "aci_rest_managed" "bgpLocalAsnP-bgpInfraPeerP" {
}
resource "aci_rest_managed" "bgpRsPeerPfxPol-bgpInfraPeerP" {
- for_each = { for peer in var.bgp_infra_peers : peer.ip => peer if peer.peer_prefix_policy != null }
+ for_each = { for peer in var.bgp_infra_peers : peer.ip => peer if(var.sr_mpls || (var.sr_mpls == false && peer.peer_type != "sr-mpls" && peer.peer_type != "vxlan-bgw")) && peer.peer_prefix_policy != null }
dn = "${aci_rest_managed.bgpInfraPeerP[each.key].dn}/rspeerPfxPol"
class_name = "bgpRsPeerPfxPol"
content = {
diff --git a/modules/terraform-aci-l3out-node-profile/variables.tf b/modules/terraform-aci-l3out-node-profile/variables.tf
index 131bdc91..c4e68dda 100644
--- a/modules/terraform-aci-l3out-node-profile/variables.tf
+++ b/modules/terraform-aci-l3out-node-profile/variables.tf
@@ -215,13 +215,17 @@ variable "sr_mpls" {
}
variable "bgp_infra_peers" {
- description = "List of BGP EVPN peers for SR MPLS L3out. Allowed values `remote_as`: 0-4294967295. Default value `allow_self_as`: false. Default value `disable_peer_as_check`: false. Default value `bfd`: false. Default value `ttl`: 2. Default value `admin_state`: true. Allowed values `local_as`: 0-4294967295. Choices `as_propagate`: `none`, `no-prepend`, `replace-as`, `dual-as`. Default value `as_propagate`: `none`."
+ description = "List of BGP peers for Infra L3out. Allowed values `remote_as`: 0-4294967295. Default value `allow_self_as`: false. Default value `disable_peer_as_check`: false. Default value `bfd`: false. Default value `ttl`: 2. Default value `admin_state`: true. Allowed values `local_as`: 0-4294967295. Choices `as_propagate`: `none`, `no-prepend`, `replace-as`, `dual-as`. Default value `as_propagate`: `none`. Choices `peer_type`: `sr-mpls`, `wan`, `mdp-wan` or `intersite`"
type = list(object({
ip = string
remote_as = string
description = optional(string, "")
allow_self_as = optional(bool, false)
disable_peer_as_check = optional(bool, false)
+ as_override = optional(bool, false)
+ next_hop_self = optional(bool, false)
+ send_community = optional(bool, false)
+ send_ext_community = optional(bool, false)
password = optional(string)
bfd = optional(bool, false)
ttl = optional(number, 1)
@@ -229,6 +233,9 @@ variable "bgp_infra_peers" {
local_as = optional(number)
as_propagate = optional(string, "none")
peer_prefix_policy = optional(string)
+ peer_type = optional(string)
+ source_interface_type = optional(string, "l3out-loopback")
+ data_plane_address = optional(string, null)
}))
default = []
@@ -266,6 +273,25 @@ variable "bgp_infra_peers" {
])
error_message = "`as_propagate`: Allowed value are: `none`, `no-prepend`, `replace-as` or `dual-as`."
}
+
+ validation {
+ condition = alltrue([
+ for b in var.bgp_infra_peers : b.peer_type == null || try(contains(["sr-mpls", "wan", "mdp-wan", "vxlan-bgw"], b.peer_type), false)
+ ])
+ error_message = "`peer_type`: Allowed value are: `sr-mpls`, `wan`, `mdp-wan` or 'vxlan-bgw'."
+ }
+ validation {
+ condition = alltrue([
+ for b in var.bgp_infra_peers : try(contains(["l3out-loopback", "routable-loopback"], b.source_interface_type), false)
+ ])
+ error_message = "`source_interface_type`: Allowed value are: `l3out-loopback` or `routable-loopback`."
+ }
+ validation {
+ condition = alltrue([
+ for b in var.bgp_infra_peers : (b.data_plane_address == null && b.source_interface_type != "routable-loopback") || b.data_plane_address != null
+ ])
+ error_message = "`data_plane_address`: Must be set if `source_interface_type` is `routable-loopback`."
+ }
}
variable "mpls_custom_qos_policy" {