Skip to content

Commit

Permalink
Support ip data plane learning at subnet level (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
jgomezve authored May 24, 2024
1 parent c545dd6 commit 4640967
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 53 deletions.
48 changes: 25 additions & 23 deletions aci_tenants.tf
Original file line number Diff line number Diff line change
Expand Up @@ -187,16 +187,17 @@ locals {
igmp_interface_policy = try("${bd.igmp_interface_policy}${local.defaults.apic.tenants.policies.igmp_interface_policies.name_suffix}", "")
igmp_snooping_policy = try("${bd.igmp_snooping_policy}${local.defaults.apic.tenants.policies.igmp_snooping_policies.name_suffix}", "")
subnets = [for subnet in try(bd.subnets, []) : {
ip = subnet.ip
description = try(subnet.description, "")
primary_ip = try(subnet.primary_ip, local.defaults.apic.tenants.bridge_domains.subnets.primary_ip)
public = try(subnet.public, local.defaults.apic.tenants.bridge_domains.subnets.public)
shared = try(subnet.shared, local.defaults.apic.tenants.bridge_domains.subnets.shared)
igmp_querier = try(subnet.igmp_querier, local.defaults.apic.tenants.bridge_domains.subnets.igmp_querier)
nd_ra_prefix = try(subnet.nd_ra_prefix, local.defaults.apic.tenants.bridge_domains.subnets.nd_ra_prefix)
no_default_gateway = try(subnet.no_default_gateway, local.defaults.apic.tenants.bridge_domains.subnets.no_default_gateway)
virtual = try(subnet.virtual, local.defaults.apic.tenants.bridge_domains.subnets.virtual)
nd_ra_prefix_policy = try("${subnet.nd_ra_prefix_policy}${local.defaults.apic.tenants.policies.nd_ra_prefix_policies.name_suffix}", "")
ip = subnet.ip
description = try(subnet.description, "")
primary_ip = try(subnet.primary_ip, local.defaults.apic.tenants.bridge_domains.subnets.primary_ip)
public = try(subnet.public, local.defaults.apic.tenants.bridge_domains.subnets.public)
shared = try(subnet.shared, local.defaults.apic.tenants.bridge_domains.subnets.shared)
igmp_querier = try(subnet.igmp_querier, local.defaults.apic.tenants.bridge_domains.subnets.igmp_querier)
nd_ra_prefix = try(subnet.nd_ra_prefix, local.defaults.apic.tenants.bridge_domains.subnets.nd_ra_prefix)
no_default_gateway = try(subnet.no_default_gateway, local.defaults.apic.tenants.bridge_domains.subnets.no_default_gateway)
virtual = try(subnet.virtual, local.defaults.apic.tenants.bridge_domains.subnets.virtual)
nd_ra_prefix_policy = try("${subnet.nd_ra_prefix_policy}${local.defaults.apic.tenants.policies.nd_ra_prefix_policies.name_suffix}", "")
ip_dataplane_learning = try(subnet.ip_dataplane_learning, null)
}]
l3outs = try(bd.l3outs, null) != null ? [for l3out in bd.l3outs : "${l3out}${local.defaults.apic.tenants.l3outs.name_suffix}"] : []
dhcp_labels = [for label in try(bd.dhcp_labels, []) : {
Expand Down Expand Up @@ -308,19 +309,20 @@ locals {
application_profile = try(master.application_profile, "${ap.name}${local.defaults.apic.tenants.application_profiles.name_suffix}")
}]
subnets = [for subnet in try(epg.subnets, []) : {
description = try(subnet.description, "")
ip = subnet.ip
public = try(subnet.public, local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.public)
shared = try(subnet.shared, local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.shared)
igmp_querier = try(subnet.igmp_querier, local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.igmp_querier)
nd_ra_prefix = try(subnet.nd_ra_prefix, local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.nd_ra_prefix)
no_default_gateway = try(subnet.no_default_gateway, local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.no_default_gateway)
nd_ra_prefix_policy = try("${subnet.nd_ra_prefix_policy}${local.defaults.apic.tenants.policies.nd_ra_prefix_policies.name_suffix}", "")
next_hop_ip = try(subnet.next_hop_ip, "")
anycast_mac = try(subnet.anycast_mac, "")
nlb_group = try(subnet.nlb_group, "0.0.0.0")
nlb_mac = try(subnet.nlb_mac, "00:00:00:00:00:00")
nlb_mode = try(subnet.nlb_mode, "")
description = try(subnet.description, "")
ip = subnet.ip
public = try(subnet.public, local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.public)
shared = try(subnet.shared, local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.shared)
igmp_querier = try(subnet.igmp_querier, local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.igmp_querier)
nd_ra_prefix = try(subnet.nd_ra_prefix, local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.nd_ra_prefix)
no_default_gateway = try(subnet.no_default_gateway, local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.no_default_gateway)
nd_ra_prefix_policy = try("${subnet.nd_ra_prefix_policy}${local.defaults.apic.tenants.policies.nd_ra_prefix_policies.name_suffix}", "")
ip_dataplane_learning = try(subnet.ip_dataplane_learning, null)
next_hop_ip = try(subnet.next_hop_ip, "")
anycast_mac = try(subnet.anycast_mac, "")
nlb_group = try(subnet.nlb_group, "0.0.0.0")
nlb_mac = try(subnet.nlb_mac, "00:00:00:00:00:00")
nlb_mode = try(subnet.nlb_mode, "")
ip_pools = [for pool in try(subnet.ip_pools, []) : {
name = "${pool.name}${local.defaults.apic.tenants.application_profiles.endpoint_groups.subnets.ip_pools.name_suffix}"
start_ip = try(pool.start_ip, "0.0.0.0")
Expand Down
2 changes: 1 addition & 1 deletion modules/terraform-aci-bridge-domain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ module "aci_bridge_domain" {
| <a name="input_vrf"></a> [vrf](#input\_vrf) | VRF name. | `string` | n/a | yes |
| <a name="input_igmp_interface_policy"></a> [igmp\_interface\_policy](#input\_igmp\_interface\_policy) | IGMP interface policy. | `string` | `""` | no |
| <a name="input_igmp_snooping_policy"></a> [igmp\_snooping\_policy](#input\_igmp\_snooping\_policy) | IGMP snooping policy. | `string` | `""` | no |
| <a name="input_subnets"></a> [subnets](#input\_subnets) | List of subnets. Default value `primary_ip`: `false`. Default value `public`: `false`. Default value `shared`: `false`. Default value `igmp_querier`: `false`. Default value `nd_ra_prefix`: `true`. Default value `no_default_gateway`: `false`. Default value `virtual`: `false`. | <pre>list(object({<br> description = optional(string, "")<br> ip = string<br> primary_ip = optional(bool, false)<br> public = optional(bool, false)<br> shared = optional(bool, false)<br> igmp_querier = optional(bool, false)<br> nd_ra_prefix = optional(bool, true)<br> no_default_gateway = optional(bool, false)<br> virtual = optional(bool, false)<br> nd_ra_prefix_policy = optional(string, "")<br> tags = optional(list(object({<br> key = string<br> value = string<br> })), [])<br> }))</pre> | `[]` | no |
| <a name="input_subnets"></a> [subnets](#input\_subnets) | List of subnets. Default value `primary_ip`: `false`. Default value `public`: `false`. Default value `shared`: `false`. Default value `igmp_querier`: `false`. Default value `nd_ra_prefix`: `true`. Default value `no_default_gateway`: `false`. Default value `virtual`: `false`. | <pre>list(object({<br> description = optional(string, "")<br> ip = string<br> primary_ip = optional(bool, false)<br> public = optional(bool, false)<br> shared = optional(bool, false)<br> igmp_querier = optional(bool, false)<br> nd_ra_prefix = optional(bool, true)<br> no_default_gateway = optional(bool, false)<br> virtual = optional(bool, false)<br> nd_ra_prefix_policy = optional(string, "")<br> ip_dataplane_learning = optional(bool, null)<br> tags = optional(list(object({<br> key = string<br> value = string<br> })), [])<br> }))</pre> | `[]` | no |
| <a name="input_l3outs"></a> [l3outs](#input\_l3outs) | List of l3outs | `list(string)` | `[]` | no |
| <a name="input_dhcp_labels"></a> [dhcp\_labels](#input\_dhcp\_labels) | List of DHCP labels | <pre>list(object({<br> dhcp_relay_policy = string<br> dhcp_option_policy = optional(string)<br> scope = optional(string, "tenant")<br> }))</pre> | `[]` | no |

Expand Down
13 changes: 7 additions & 6 deletions modules/terraform-aci-bridge-domain/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ resource "aci_rest_managed" "fvSubnet" {
dn = "${aci_rest_managed.fvBD.dn}/subnet-[${each.value.ip}]"
class_name = "fvSubnet"
content = {
ip = each.value.ip
descr = each.value.description
preferred = each.value.primary_ip == true ? "yes" : "no"
ctrl = join(",", concat(each.value.nd_ra_prefix == true ? ["nd"] : [], each.value.no_default_gateway == true ? ["no-default-gateway"] : [], each.value.igmp_querier == true ? ["querier"] : []))
scope = join(",", concat(each.value.public == true ? ["public"] : ["private"], each.value.shared == true ? ["shared"] : []))
virtual = each.value.virtual == true ? "yes" : "no"
ip = each.value.ip
descr = each.value.description
preferred = each.value.primary_ip == true ? "yes" : "no"
ctrl = join(",", concat(each.value.nd_ra_prefix == true ? ["nd"] : [], each.value.no_default_gateway == true ? ["no-default-gateway"] : [], each.value.igmp_querier == true ? ["querier"] : []))
scope = join(",", concat(each.value.public == true ? ["public"] : ["private"], each.value.shared == true ? ["shared"] : []))
virtual = each.value.virtual == true ? "yes" : "no"
ipDPLearning = each.value.ip_dataplane_learning != null ? (each.value.ip_dataplane_learning == true ? "enabled" : "disabled") : null
}

depends_on = [
Expand Down
21 changes: 11 additions & 10 deletions modules/terraform-aci-bridge-domain/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -186,16 +186,17 @@ variable "igmp_snooping_policy" {
variable "subnets" {
description = "List of subnets. Default value `primary_ip`: `false`. Default value `public`: `false`. Default value `shared`: `false`. Default value `igmp_querier`: `false`. Default value `nd_ra_prefix`: `true`. Default value `no_default_gateway`: `false`. Default value `virtual`: `false`."
type = list(object({
description = optional(string, "")
ip = string
primary_ip = optional(bool, false)
public = optional(bool, false)
shared = optional(bool, false)
igmp_querier = optional(bool, false)
nd_ra_prefix = optional(bool, true)
no_default_gateway = optional(bool, false)
virtual = optional(bool, false)
nd_ra_prefix_policy = optional(string, "")
description = optional(string, "")
ip = string
primary_ip = optional(bool, false)
public = optional(bool, false)
shared = optional(bool, false)
igmp_querier = optional(bool, false)
nd_ra_prefix = optional(bool, true)
no_default_gateway = optional(bool, false)
virtual = optional(bool, false)
nd_ra_prefix_policy = optional(string, "")
ip_dataplane_learning = optional(bool, null)
tags = optional(list(object({
key = string
value = string
Expand Down
2 changes: 1 addition & 1 deletion modules/terraform-aci-endpoint-group/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ module "aci_endpoint_group" {
| <a name="input_contract_intra_epgs"></a> [contract\_intra\_epgs](#input\_contract\_intra\_epgs) | List of intra-EPG contracts. | `list(string)` | `[]` | no |
| <a name="input_contract_masters"></a> [contract\_masters](#input\_contract\_masters) | List of EPG contract masters. | <pre>list(object({<br> endpoint_group = string<br> application_profile = optional(string, "")<br> }))</pre> | `[]` | no |
| <a name="input_physical_domains"></a> [physical\_domains](#input\_physical\_domains) | List of physical domains. | `list(string)` | `[]` | no |
| <a name="input_subnets"></a> [subnets](#input\_subnets) | List of subnets. Default value `public`: `false`. Default value `shared`: `false`. Default value `igmp_querier`: `false`. Default value `nd_ra_prefix`: `true`. Default value `no_default_gateway`: `false`. `nlb_mode` allowed values: `mode-mcast-igmp`, `mode-uc` or `mode-mcast-static`. | <pre>list(object({<br> description = optional(string, "")<br> ip = string<br> public = optional(bool, false)<br> shared = optional(bool, false)<br> igmp_querier = optional(bool, false)<br> nd_ra_prefix = optional(bool, true)<br> no_default_gateway = optional(bool, false)<br> nd_ra_prefix_policy = optional(string, "")<br> ip_pools = optional(list(object({<br> name = string<br> start_ip = optional(string, "0.0.0.0")<br> end_ip = optional(string, "0.0.0.0")<br> dns_search_suffix = optional(string, "")<br> dns_server = optional(string, "")<br> dns_suffix = optional(string, "")<br> wins_server = optional(string, "")<br> })), [])<br> next_hop_ip = optional(string, "")<br> anycast_mac = optional(string, "")<br> nlb_group = optional(string, "0.0.0.0")<br> nlb_mac = optional(string, "00:00:00:00:00:00")<br> nlb_mode = optional(string, "")<br> }))</pre> | `[]` | no |
| <a name="input_subnets"></a> [subnets](#input\_subnets) | List of subnets. Default value `public`: `false`. Default value `shared`: `false`. Default value `igmp_querier`: `false`. Default value `nd_ra_prefix`: `true`. Default value `no_default_gateway`: `false`. `nlb_mode` allowed values: `mode-mcast-igmp`, `mode-uc` or `mode-mcast-static`. | <pre>list(object({<br> description = optional(string, "")<br> ip = string<br> public = optional(bool, false)<br> shared = optional(bool, false)<br> igmp_querier = optional(bool, false)<br> nd_ra_prefix = optional(bool, true)<br> no_default_gateway = optional(bool, false)<br> nd_ra_prefix_policy = optional(string, "")<br> ip_dataplane_learning = optional(bool, null)<br> ip_pools = optional(list(object({<br> name = string<br> start_ip = optional(string, "0.0.0.0")<br> end_ip = optional(string, "0.0.0.0")<br> dns_search_suffix = optional(string, "")<br> dns_server = optional(string, "")<br> dns_suffix = optional(string, "")<br> wins_server = optional(string, "")<br> })), [])<br> next_hop_ip = optional(string, "")<br> anycast_mac = optional(string, "")<br> nlb_group = optional(string, "0.0.0.0")<br> nlb_mac = optional(string, "00:00:00:00:00:00")<br> nlb_mode = optional(string, "")<br> }))</pre> | `[]` | no |
| <a name="input_vmware_vmm_domains"></a> [vmware\_vmm\_domains](#input\_vmware\_vmm\_domains) | List of VMware VMM domains. Default value `u_segmentation`: `false`. Default value `netflow`: `false`. Choices `deployment_immediacy`: `immediate`, `lazy`. Default value `deployment_immediacy`: `lazy`. Choices `resolution_immediacy`: `immediate`, `lazy`, `pre-provision`. Default value `resolution_immediacy`: `immediate`. Default value `allow_promiscuous`: `false`. Default value `forged_transmits`: `false`. Default value `mac_changes`: `false`. | <pre>list(object({<br> name = string<br> u_segmentation = optional(bool, false)<br> delimiter = optional(string, "")<br> vlan = optional(number)<br> primary_vlan = optional(number)<br> secondary_vlan = optional(number)<br> netflow = optional(bool, false)<br> deployment_immediacy = optional(string, "lazy")<br> resolution_immediacy = optional(string, "immediate")<br> allow_promiscuous = optional(bool, false)<br> forged_transmits = optional(bool, false)<br> mac_changes = optional(bool, false)<br> custom_epg_name = optional(string, "")<br> elag = optional(string, "")<br> active_uplinks_order = optional(string, "")<br> standby_uplinks = optional(string, "")<br> }))</pre> | `[]` | no |
| <a name="input_static_leafs"></a> [static\_leafs](#input\_static\_leafs) | List of static leaf switches. Allowed values `pod_id`: `1` - `255`. Default value `pod_id`: `1`. Allowed values `node_id`: `1` - `4000`. Allowed values `vlan`: `1` - `4096`. Choices `mode`: `regular`, `native`, `untagged`. Default value `mode`: `regular`. Choices `deployment_immediacy`: `immediate`, `lazy`. Default value `deployment_immediacy`: `immediate` | <pre>list(object({<br> pod_id = optional(number, 1)<br> node_id = number<br> vlan = number<br> mode = optional(string, "regular")<br> deployment_immediacy = optional(string, "immediate")<br> }))</pre> | `[]` | no |
| <a name="input_static_ports"></a> [static\_ports](#input\_static\_ports) | List of static ports. Allowed values `node_id`, `node2_id`: `1` - `4000`. Allowed values `fex_id`, `fex2_id`: `101` - `199`. Allowed values `vlan`: `1` - `4096`. Allowed values `pod_id`: `1` - `255`. Default value `pod_id`: `1`. Allowed values `port`: `1` - `127`. Allowed values `sub_port`: `1` - `16`. Allowed values `module`: `1` - `9`. Default value `module`: `1`. Choices `deployment_immediacy`: `immediate`, `lazy`. Default value `deployment_immediacy`: `lazy`. Choices `mode`: `regular`, `native`, `untagged`. Default value `mode`: `regular`. | <pre>list(object({<br> node_id = number<br> node2_id = optional(number)<br> fex_id = optional(number)<br> fex2_id = optional(number)<br> vlan = number<br> pod_id = optional(number, 1)<br> port = optional(number)<br> sub_port = optional(number)<br> module = optional(number, 1)<br> channel = optional(string)<br> deployment_immediacy = optional(string, "lazy")<br> mode = optional(string, "regular")<br> ptp_source_ip = optional(string, "0.0.0.0")<br> ptp_mode = optional(string, "multicast")<br> ptp_profile = optional(string)<br> }))</pre> | `[]` | no |
Expand Down
9 changes: 5 additions & 4 deletions modules/terraform-aci-endpoint-group/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ resource "aci_rest_managed" "fvSubnet" {
dn = "${aci_rest_managed.fvAEPg.dn}/subnet-[${each.value.ip}]"
class_name = "fvSubnet"
content = {
ip = each.value.ip
descr = each.value.description != null ? each.value.description : ""
ctrl = join(",", concat(each.value.nd_ra_prefix == true ? ["nd"] : [], each.value.no_default_gateway == true ? ["no-default-gateway"] : [], each.value.igmp_querier == true ? ["querier"] : []))
scope = join(",", concat(each.value.public == true ? ["public"] : ["private"], each.value.shared == true ? ["shared"] : []))
ip = each.value.ip
descr = each.value.description != null ? each.value.description : ""
ctrl = join(",", concat(each.value.nd_ra_prefix == true ? ["nd"] : [], each.value.no_default_gateway == true ? ["no-default-gateway"] : [], each.value.igmp_querier == true ? ["querier"] : []))
scope = join(",", concat(each.value.public == true ? ["public"] : ["private"], each.value.shared == true ? ["shared"] : []))
ipDPLearning = each.value.ip_dataplane_learning != null ? (each.value.ip_dataplane_learning == true ? "enabled" : "disabled") : null
}
}

Expand Down
Loading

0 comments on commit 4640967

Please sign in to comment.