Skip to content

Commit

Permalink
Support MicroBFD (#102)
Browse files Browse the repository at this point in the history
* Support microbfd

* Update variable validation

* Merge branch 'main' into jg-micro-bfd

---------

Co-authored-by: jgomezve <[email protected]>
Co-authored-by: student <[email protected]>
  • Loading branch information
3 people authored Jul 26, 2024
1 parent 77e042d commit 67164fd
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 70 deletions.
104 changes: 56 additions & 48 deletions aci_tenants.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}]
}
]
Expand Down Expand Up @@ -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 = [
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 = [
Expand Down
3 changes: 2 additions & 1 deletion modules/terraform-aci-l3out-interface-profile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ module "aci_l3out_interface_profile" {
| <a name="input_igmp_interface_policy"></a> [igmp\_interface\_policy](#input\_igmp\_interface\_policy) | IGMP interface policy name. | `string` | `""` | no |
| <a name="input_qos_class"></a> [qos\_class](#input\_qos\_class) | QoS class. Choices: `level1`, `level2`, `level3`, `level4`, `level5`, `level6`, `unspecified`. | `string` | `"unspecified"` | no |
| <a name="input_custom_qos_policy"></a> [custom\_qos\_policy](#input\_custom\_qos\_policy) | Custom QoS policy name. | `string` | `""` | no |
| <a name="input_interfaces"></a> [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. | <pre>list(object({<br> description = optional(string, "")<br> type = optional(string, "access")<br> node_id = number<br> node2_id = optional(number)<br> pod_id = optional(number, 1)<br> module = optional(number, 1)<br> port = optional(number)<br> sub_port = optional(number)<br> channel = optional(string)<br> ip = optional(string)<br> svi = optional(bool, false)<br> autostate = optional(bool, false)<br> floating_svi = optional(bool, false)<br> vlan = optional(number)<br> mac = optional(string, "00:22:BD:F8:19:FF")<br> mtu = optional(string, "inherit")<br> mode = optional(string, "regular")<br> ip_a = optional(string)<br> ip_b = optional(string)<br> ip_shared = optional(string)<br> scope = optional(string, "local")<br> multipod_direct = optional(bool, false)<br> bgp_peers = optional(list(object({<br> ip = string<br> remote_as = string<br> description = optional(string, "")<br> allow_self_as = optional(bool, false)<br> as_override = optional(bool, false)<br> disable_peer_as_check = optional(bool, false)<br> next_hop_self = optional(bool, false)<br> send_community = optional(bool, false)<br> send_ext_community = optional(bool, false)<br> password = optional(string)<br> allowed_self_as_count = optional(number, 3)<br> bfd = optional(bool, false)<br> disable_connected_check = optional(bool, false)<br> ttl = optional(number, 1)<br> weight = optional(number, 0)<br> remove_all_private_as = optional(bool, false)<br> remove_private_as = optional(bool, false)<br> replace_private_as_with_local_as = optional(bool, false)<br> unicast_address_family = optional(bool, true)<br> multicast_address_family = optional(bool, true)<br> admin_state = optional(bool, true)<br> local_as = optional(number)<br> as_propagate = optional(string, "none")<br> peer_prefix_policy = optional(string)<br> export_route_control = optional(string)<br> import_route_control = optional(string)<br> })), [])<br> paths = optional(list(object({<br> physical_domain = optional(string)<br> vmware_vmm_domain = optional(string)<br> elag = optional(string)<br> floating_ip = string<br> })), [])<br> }))</pre> | `[]` | no |
| <a name="input_interfaces"></a> [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. | <pre>list(object({<br> description = optional(string, "")<br> type = optional(string, "access")<br> node_id = number<br> node2_id = optional(number)<br> pod_id = optional(number, 1)<br> module = optional(number, 1)<br> port = optional(number)<br> sub_port = optional(number)<br> channel = optional(string)<br> ip = optional(string)<br> svi = optional(bool, false)<br> autostate = optional(bool, false)<br> floating_svi = optional(bool, false)<br> vlan = optional(number)<br> mac = optional(string, "00:22:BD:F8:19:FF")<br> mtu = optional(string, "inherit")<br> mode = optional(string, "regular")<br> ip_a = optional(string)<br> ip_b = optional(string)<br> ip_shared = optional(string)<br> scope = optional(string, "local")<br> multipod_direct = optional(bool, false)<br> bgp_peers = optional(list(object({<br> ip = string<br> remote_as = string<br> description = optional(string, "")<br> allow_self_as = optional(bool, false)<br> as_override = optional(bool, false)<br> disable_peer_as_check = optional(bool, false)<br> next_hop_self = optional(bool, false)<br> send_community = optional(bool, false)<br> send_ext_community = optional(bool, false)<br> password = optional(string)<br> allowed_self_as_count = optional(number, 3)<br> bfd = optional(bool, false)<br> disable_connected_check = optional(bool, false)<br> ttl = optional(number, 1)<br> weight = optional(number, 0)<br> remove_all_private_as = optional(bool, false)<br> remove_private_as = optional(bool, false)<br> replace_private_as_with_local_as = optional(bool, false)<br> unicast_address_family = optional(bool, true)<br> multicast_address_family = optional(bool, true)<br> admin_state = optional(bool, true)<br> local_as = optional(number)<br> as_propagate = optional(string, "none")<br> peer_prefix_policy = optional(string)<br> export_route_control = optional(string)<br> import_route_control = optional(string)<br> })), [])<br> paths = optional(list(object({<br> physical_domain = optional(string)<br> vmware_vmm_domain = optional(string)<br> elag = optional(string)<br> floating_ip = string<br> })), [])<br> micro_bfd_destination_ip = optional(string, "")<br> micro_bfd_start_timer = optional(number, 0)<br> }))</pre> | `[]` | no |
| <a name="input_multipod"></a> [multipod](#input\_multipod) | Multipod L3out flag. | `bool` | `false` | no |
| <a name="input_remote_leaf"></a> [remote\_leaf](#input\_remote\_leaf) | Remote leaf L3out flag. | `bool` | `false` | no |
| <a name="input_sr_mpls"></a> [sr\_mpls](#input\_sr\_mpls) | SR MPLS L3out flag. | `bool` | `false` | no |
Expand All @@ -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 |
Expand Down
55 changes: 34 additions & 21 deletions modules/terraform-aci-l3out-interface-profile/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
])
Expand Down Expand Up @@ -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}]"
Expand Down
Loading

0 comments on commit 67164fd

Please sign in to comment.