diff --git a/aci_tenants.tf b/aci_tenants.tf index c5dc0b22..b1ab5266 100644 --- a/aci_tenants.tf +++ b/aci_tenants.tf @@ -1167,6 +1167,8 @@ locals { elag = try(path.elag, null) floating_ip = path.floating_ip }] + micro_bfd_destination_ip = try(int.micro_bfd.destination_ip, null) + micro_bfd_start_timer = try(int.micro_bfd.start_timer, null) }] } ] @@ -1199,30 +1201,32 @@ module "aci_l3out_interface_profile_manual" { qos_class = each.value.qos_class custom_qos_policy = each.value.custom_qos_policy interfaces = [for int in try(each.value.interfaces, []) : { - ip = int.ip - svi = int.svi - floating_svi = int.floating_svi - autostate = int.autostate - vlan = int.vlan - description = int.description - type = int.type - mac = int.mac - mtu = int.mtu - mode = int.mode - node_id = int.node_id - node2_id = int.node2_id == "vpc" ? [for pg in local.leaf_interface_policy_group_mapping : try(pg.node_ids, []) if pg.name == int.channel][0][1] : int.node2_id - pod_id = int.pod_id == null ? try([for node in local.node_policies.nodes : node.pod if node.id == int.node_id][0], local.defaults.apic.tenants.l3outs.node_profiles.interface_profiles.interfaces.pod) : int.pod_id - module = int.module - port = int.port - sub_port = int.sub_port - channel = int.channel - ip_a = int.ip_a - ip_b = int.ip_b - ip_shared = int.ip_shared - bgp_peers = int.bgp_peers - paths = int.paths - scope = int.scope - multipod_direct = int.multipod_direct + ip = int.ip + svi = int.svi + floating_svi = int.floating_svi + autostate = int.autostate + vlan = int.vlan + description = int.description + type = int.type + mac = int.mac + mtu = int.mtu + mode = int.mode + node_id = int.node_id + node2_id = int.node2_id == "vpc" ? [for pg in local.leaf_interface_policy_group_mapping : try(pg.node_ids, []) if pg.name == int.channel][0][1] : int.node2_id + pod_id = int.pod_id == null ? try([for node in local.node_policies.nodes : node.pod if node.id == int.node_id][0], local.defaults.apic.tenants.l3outs.node_profiles.interface_profiles.interfaces.pod) : int.pod_id + module = int.module + port = int.port + sub_port = int.sub_port + channel = int.channel + ip_a = int.ip_a + ip_b = int.ip_b + ip_shared = int.ip_shared + bgp_peers = int.bgp_peers + paths = int.paths + scope = int.scope + multipod_direct = int.multipod_direct + micro_bfd_destination_ip = int.micro_bfd_destination_ip + micro_bfd_start_timer = int.micro_bfd_start_timer }] depends_on = [ @@ -1312,6 +1316,8 @@ locals { elag = try(path.elag, null) floating_ip = path.floating_ip }] + micro_bfd_destination_ip = try(int.micro_bfd.destination_ip, null) + micro_bfd_start_timer = try(int.micro_bfd.start_timer, null) } ]]) } if length(try(l3out.nodes, [])) != 0 @@ -1342,30 +1348,32 @@ module "aci_l3out_interface_profile_auto" { qos_class = each.value.qos_class custom_qos_policy = each.value.custom_qos_policy interfaces = [for int in try(each.value.interfaces, []) : { - ip = int.ip - svi = int.svi - autostate = int.autostate - floating_svi = int.floating_svi - vlan = int.vlan - description = int.description - type = int.type - mac = int.mac - mtu = int.mtu - mode = int.mode - node_id = int.node_id - node2_id = int.node2_id == "vpc" ? [for pg in local.leaf_interface_policy_group_mapping : try(pg.node_ids, []) if pg.name == int.channel][0][1] : int.node2_id - pod_id = int.pod_id - module = int.module - port = int.port - sub_port = int.sub_port - channel = int.channel - ip_a = int.ip_a - ip_b = int.ip_b - ip_shared = int.ip_shared - bgp_peers = int.bgp_peers - paths = int.paths - scope = int.scope - multipod_direct = int.multipod_direct + ip = int.ip + svi = int.svi + autostate = int.autostate + floating_svi = int.floating_svi + vlan = int.vlan + description = int.description + type = int.type + mac = int.mac + mtu = int.mtu + mode = int.mode + node_id = int.node_id + node2_id = int.node2_id == "vpc" ? [for pg in local.leaf_interface_policy_group_mapping : try(pg.node_ids, []) if pg.name == int.channel][0][1] : int.node2_id + pod_id = int.pod_id + module = int.module + port = int.port + sub_port = int.sub_port + channel = int.channel + ip_a = int.ip_a + ip_b = int.ip_b + ip_shared = int.ip_shared + bgp_peers = int.bgp_peers + paths = int.paths + scope = int.scope + multipod_direct = int.multipod_direct + micro_bfd_destination_ip = int.micro_bfd_destination_ip + micro_bfd_start_timer = int.micro_bfd_start_timer }] depends_on = [ diff --git a/modules/terraform-aci-l3out-interface-profile/README.md b/modules/terraform-aci-l3out-interface-profile/README.md index 817f1293..018e80f5 100644 --- a/modules/terraform-aci-l3out-interface-profile/README.md +++ b/modules/terraform-aci-l3out-interface-profile/README.md @@ -110,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({| `[]` | 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. |
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)
sub_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
})), [])
}))
list(object({| `[]` | 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 | @@ -128,6 +128,7 @@ module "aci_l3out_interface_profile" { | Name | Type | |------|------| | [aci_rest_managed.bfdIfP](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource | +| [aci_rest_managed.bfdMicroBfdP](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource | | [aci_rest_managed.bfdRsIfPol](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource | | [aci_rest_managed.bgpAsP](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource | | [aci_rest_managed.bgpAsP_floating](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource | diff --git a/modules/terraform-aci-l3out-interface-profile/main.tf b/modules/terraform-aci-l3out-interface-profile/main.tf index a5ad3fb6..6759596c 100644 --- a/modules/terraform-aci-l3out-interface-profile/main.tf +++ b/modules/terraform-aci-l3out-interface-profile/main.tf @@ -3,27 +3,29 @@ locals { for int in var.interfaces : { key = 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}]" : (int.sub_port != null ? "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[eth${int.module}/${int.port}/${int.sub_port}]" : "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[eth${int.module}/${int.port}]")) value = { - ip = int.type != "vpc" ? int.ip : "0.0.0.0" - svi = int.svi == true ? "yes" : "no" - description = int.description - type = int.type - vlan = int.vlan - autostate = int.autostate ? "enabled" : "disabled" - mac = int.mac - mode = int.mode - mtu = int.mtu - node_id = int.node_id - node2_id = int.node2_id - module = int.module - pod_id = int.pod_id - port = int.port - channel = int.channel - ip_a = int.ip_a - ip_b = int.ip_b - 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}]" : (int.sub_port != null ? "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[eth${int.module}/${int.port}/${int.sub_port}]" : "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[eth${int.module}/${int.port}]")) - multipod_direct = int.multipod_direct - scope = int.scope + ip = int.type != "vpc" ? int.ip : "0.0.0.0" + svi = int.svi == true ? "yes" : "no" + description = int.description + type = int.type + vlan = int.vlan + autostate = int.autostate ? "enabled" : "disabled" + mac = int.mac + mode = int.mode + mtu = int.mtu + node_id = int.node_id + node2_id = int.node2_id + module = int.module + pod_id = int.pod_id + port = int.port + channel = int.channel + ip_a = int.ip_a + ip_b = int.ip_b + 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}]" : (int.sub_port != null ? "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[eth${int.module}/${int.port}/${int.sub_port}]" : "topology/pod-${int.pod_id}/paths-${int.node_id}/pathep-[eth${int.module}/${int.port}]")) + multipod_direct = int.multipod_direct + scope = int.scope + micro_bfd_destination_ip = int.micro_bfd_destination_ip + micro_bfd_start_timer = int.micro_bfd_start_timer } } if int.floating_svi == false ]) @@ -326,6 +328,17 @@ resource "aci_rest_managed" "l3extIp_B" { } } +resource "aci_rest_managed" "bfdMicroBfdP" { + for_each = { for item in local.interfaces : item.key => item.value if item.value.micro_bfd_destination_ip != "" && item.value.micro_bfd_destination_ip != null } + dn = "${aci_rest_managed.l3extRsPathL3OutAtt[each.key].dn}/microBfdP" + class_name = "bfdMicroBfdP" + content = { + adminState = "yes" + dst = each.value.micro_bfd_destination_ip + stTm = each.value.micro_bfd_start_timer + } +} + resource "aci_rest_managed" "l3extVirtualLIfP" { for_each = { for item in local.floating_interfaces : item.key => item.value } dn = "${aci_rest_managed.l3extLIfP.dn}/vlifp-[topology/pod-${each.value.pod_id}/node-${each.value.node_id}]-[vlan-${each.value.vlan}]" diff --git a/modules/terraform-aci-l3out-interface-profile/variables.tf b/modules/terraform-aci-l3out-interface-profile/variables.tf index fa32c4ab..ec0ae32b 100644 --- a/modules/terraform-aci-l3out-interface-profile/variables.tf +++ b/modules/terraform-aci-l3out-interface-profile/variables.tf @@ -236,6 +236,8 @@ variable "interfaces" { elag = optional(string) floating_ip = string })), []) + micro_bfd_destination_ip = optional(string, "") + micro_bfd_start_timer = optional(number, 0) })) default = [] @@ -406,6 +408,13 @@ variable "interfaces" { ])) error_message = "`paths.elag`: Allowed characters: `a`-`z`, `A`-`Z`, `0`-`9`, `_`, `.`, `:`, `-`. Maximum characters: 64." } + + validation { + condition = alltrue([ + for i in var.interfaces : i.micro_bfd_start_timer == null || try(i.micro_bfd_start_timer == 0 || try(i.micro_bfd_start_timer >= 60 && i.micro_bfd_start_timer <= 3600, false), false) + ]) + error_message = "`interfaces.micro_bfd_start_timer`: Minimum value: `60`. Maximum value: `3600`." + } } variable "multipod" {
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)
sub_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
})), [])
micro_bfd_destination_ip = optional(string, "")
micro_bfd_start_timer = optional(number, 0)
}))