diff --git a/README.md b/README.md index 34a33353..e4d17f9a 100644 --- a/README.md +++ b/README.md @@ -255,6 +255,7 @@ Additional example repositories: | [aci\_monitoring\_policy](#module\_aci\_monitoring\_policy) | ./modules/terraform-aci-monitoring-policy | n/a | | [aci\_mst\_policy](#module\_aci\_mst\_policy) | ./modules/terraform-aci-mst-policy | n/a | | [aci\_multicast\_route\_map](#module\_aci\_multicast\_route\_map) | ./modules/terraform-aci-multicast-route-map | n/a | +| [aci\_nd\_interface\_policy](#module\_aci\_nd\_interface\_policy) | ./modules/terraform-aci-nd-interface-policy | n/a | | [aci\_nd\_ra\_prefix\_policy](#module\_aci\_nd\_ra\_prefix\_policy) | ./modules/terraform-aci-nd-ra-prefix-policy | n/a | | [aci\_node\_control\_policy](#module\_aci\_node\_control\_policy) | ./modules/terraform-aci-node-control-policy | n/a | | [aci\_node\_registration](#module\_aci\_node\_registration) | ./modules/terraform-aci-node-registration | n/a | diff --git a/aci_tenants.tf b/aci_tenants.tf index 312b3f9a..9afa0173 100644 --- a/aci_tenants.tf +++ b/aci_tenants.tf @@ -2626,6 +2626,56 @@ locals { ]) } +locals { + nd_interface_policies = flatten([ + for tenant in local.tenants : [ + for policy in try(tenant.policies.nd_interface_policies, []) : { + key = format("%s/%s", tenant.name, policy.name) + tenant = tenant.name + name = "${policy.name}${local.defaults.apic.tenants.policies.nd_interface_policies.name_suffix}" + description = try(policy.description, "") + controller_state = [for state in try(policy.controller_state, []) : state] + hop_limit = try(policy.hop_limit, local.defaults.apic.tenants.policies.nd_interface_policies.hop_limit) + ns_tx_interval = try(policy.ns_tx_interval, local.defaults.apic.tenants.policies.nd_interface_policies.ns_tx_interval) + mtu = try(policy.mtu, local.defaults.apic.tenants.policies.nd_interface_policies.mtu) + retransmit_retry_count = try(policy.retransmit_retry_count, local.defaults.apic.tenants.policies.nd_interface_policies.retransmit_retry_count) + nud_retransmit_base = try(policy.nud_retransmit_base, local.defaults.apic.tenants.policies.nd_interface_policies.nud_retransmit_base) + nud_retransmit_interval = try(policy.nud_retransmit_interval, local.defaults.apic.tenants.policies.nd_interface_policies.nud_retransmit_interval) + nud_retransmit_count = try(policy.nud_retransmit_count, local.defaults.apic.tenants.policies.nd_interface_policies.nud_retransmit_count) + route_advertise_interval = try(policy.route_advertise_interval, local.defaults.apic.tenants.policies.nd_interface_policies.route_advertise_interval) + router_lifetime = try(policy.router_lifetime, local.defaults.apic.tenants.policies.nd_interface_policies.router_lifetime) + reachable_time = try(policy.reachable_time, local.defaults.apic.tenants.policies.nd_interface_policies.reachable_time) + retransmit_timer = try(policy.retransmit_retry_count, local.defaults.apic.tenants.policies.nd_interface_policies.retransmit_timer) + } + ] + ]) +} + +module "aci_nd_interface_policy" { + source = "./modules/terraform-aci-nd-interface-policy" + + for_each = { for pol in local.nd_interface_policies : pol.key => pol if local.modules.aci_nd_interface_policy && var.manage_tenants } + tenant = each.value.tenant + name = each.value.name + description = each.value.description + controller_state = each.value.controller_state + hop_limit = each.value.hop_limit + ns_tx_interval = each.value.ns_tx_interval + mtu = each.value.mtu + retransmit_retry_count = each.value.retransmit_retry_count + nud_retransmit_base = each.value.nud_retransmit_base + nud_retransmit_interval = each.value.nud_retransmit_interval + nud_retransmit_count = each.value.nud_retransmit_count + route_advertise_interval = each.value.route_advertise_interval + router_lifetime = each.value.router_lifetime + reachable_time = each.value.reachable_time + retransmit_timer = each.value.retransmit_timer + + depends_on = [ + module.aci_tenant, + ] +} + module "aci_nd_ra_prefix_policy" { source = "./modules/terraform-aci-nd-ra-prefix-policy" diff --git a/defaults/defaults.yaml b/defaults/defaults.yaml index 553e644c..b86eb473 100644 --- a/defaults/defaults.yaml +++ b/defaults/defaults.yaml @@ -1256,6 +1256,19 @@ defaults: detection_multiplier: 3 min_rx_interval: 250 min_tx_interval: 250 + nd_interface_policies: + name_suffix: "" + hop_limit: 64 + ns_tx_interval: 1000 + mtu: 9000 + retransmit_retry_count: 3 + nud_retransmit_base: 1 + nud_retransmit_interval: 1000 + nud_retransmit_count: 3 + route_advertise_interval: 600 + router_lifetime: 1800 + reachable_time: 0 + retransmit_timer: 0 nd_ra_prefix_policies: name_suffix: "" valid_lifetime: 2592000 diff --git a/defaults/modules.yaml b/defaults/modules.yaml index 4e096815..146b71a0 100644 --- a/defaults/modules.yaml +++ b/defaults/modules.yaml @@ -97,6 +97,7 @@ modules: aci_monitoring_policy: true aci_mst_policy: true aci_multicast_route_map: true + aci_nd_interface_policy: true aci_nd_ra_prefix_policy: true aci_node_control_policy: true aci_node_registration: true diff --git a/modules/terraform-aci-nd-interface-policy/.terraform-docs.yml b/modules/terraform-aci-nd-interface-policy/.terraform-docs.yml new file mode 100644 index 00000000..280f9791 --- /dev/null +++ b/modules/terraform-aci-nd-interface-policy/.terraform-docs.yml @@ -0,0 +1,34 @@ +version: '>= 0.0.1' + +formatter: markdown table + +content: |- + # Terraform ACI ND Interface Policy Module + + Manages ACI ND Interface Policy + + Location in GUI: + `Tenants` » `XXX` » `Policies` » `Protocol` » `ND Interface` + + ## Examples + + ```hcl + {{ include "./examples/complete/main.tf" }} + ``` + + {{ .Requirements }} + + {{ .Providers }} + + {{ .Inputs }} + + {{ .Outputs }} + + {{ .Resources }} + +output: + file: README.md + mode: replace + +sort: + enabled: false diff --git a/modules/terraform-aci-nd-interface-policy/README.md b/modules/terraform-aci-nd-interface-policy/README.md new file mode 100644 index 00000000..14eb75e4 --- /dev/null +++ b/modules/terraform-aci-nd-interface-policy/README.md @@ -0,0 +1,79 @@ + +# Terraform ACI ND Interface Policy Module + +Manages ACI ND Interface Policy + +Location in GUI: +`Tenants` » `XXX` » `Policies` » `Protocol` » `ND Interface` + +## Examples + +```hcl +module "aci_nd_interface_policy" { + source = "netascode/nac-aci/aci//modules/terraform-aci-nd-interface-policy" + version = ">= 0.8.0" + + tenant = "ABC" + name = "ND-INTF-POL1" + description = "My Description" + controller_state = ["other-cfg"] + hop_limit = 32 + ns_tx_interval = 1000 + mtu = 9000 + retransmit_retry_count = 3 + nud_retransmit_base = 1 + nud_retransmit_interval = 2000 + nud_retransmit_count = 3 + route_advertise_interval = 600 + router_lifetime = 3600 + reachable_time = 0 + retransmit_timer = 0 +} +``` + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0.0 | +| [aci](#requirement\_aci) | >= 2.0.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aci](#provider\_aci) | >= 2.0.0 | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [tenant](#input\_tenant) | Tenant name. | `string` | n/a | yes | +| [name](#input\_name) | ND interface policy name. | `string` | n/a | yes | +| [description](#input\_description) | Description. | `string` | `""` | no | +| [controller\_state](#input\_controller_state) | Controller administrative state. Choices: `managed-cfg`, `other-cfg`, `suppress-ra`, `suppress-ra-mtu`, `unsolicit-na-glean`. | `list` | `[]` | no | +| [hop\_limit](#input\_hop\_limit) | Hop limit. Minimum value: 1. Maximum value: 255. | `number` | `64` | no | +| [ns\_tx\_interval](#input\_ns\_tx\_interval) | NS transmit interval. Minimum value: 1000. Maximum value: 3600000 | `number` | `1000` | no | +| [mtu](#input\_mtu) | Maximum transmission unit. Minimum value: 1280. Maximum value: 9000. | `number` | `9000` | no | +| [retransmit\_retry\_count](#input\_retransmit\_retry\_count) | Retransmission retry count. Minimum value: 1. Maximum value: 100. | `number` | `3` | no | +| [nud\_retransmit\_base](#input\_nud\_retransmit\_base) | NUD retransmission base. Minimum value: 1. Maximum value: 3. | `number` | `1` | no | +| [nud\_retransmit\_interval](#input\_nud\_retransmit\_interval) | NUD retransmission interval (msec). Minimum value: 1000. Maximum value: 10000. | `number` | `1000` | no | +| [nud\_retransmit\_count](#input\_nud\_retransmit\_count) | NUD retransmission count. Minimum value: 1. Maximum value: 3. | `number` | `1` | no | +| [route\_advertise\_interval](#input\_route\_advertise\_interval) | Route advertise interval. Minimum value: 4. Maximum value: 1800. | `number` | `600` | no | +| [router\_lifetime](#input\_router\_lifetime) | Router lifetime. Minimum value: 0. Maximum value: 9000. | `number` | `1800` | no | +| [reachable\_time](#input\_reachable\_time) | Reachable time (msec). Minimum value: 0. Maximum value: 3600000. | `number` | `0` | no | +| [retransmit\_timer](#input\_retransmit\_timer) | Retransmit timer (msec). Minimum value: 0. Maximum value: 4294967295. | `number` | `0` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [dn](#output\_dn) | Distinguished name of `ndIfPol` object. | +| [name](#output\_name) | ND interface policy name. | + +## Resources + +| Name | Type | +|------|------| +| [aci_rest_managed.ndIfPol](https://registry.terraform.io/providers/CiscoDevNet/aci/latest/docs/resources/rest_managed) | resource | + \ No newline at end of file diff --git a/modules/terraform-aci-nd-interface-policy/examples/complete/.terraform-docs.yml b/modules/terraform-aci-nd-interface-policy/examples/complete/.terraform-docs.yml new file mode 100644 index 00000000..490eb625 --- /dev/null +++ b/modules/terraform-aci-nd-interface-policy/examples/complete/.terraform-docs.yml @@ -0,0 +1,24 @@ +version: '>= 0.0.1' + +formatter: markdown table + +content: |- + # ND Interface Policy Example + + To run this example you need to execute: + + ```bash + $ terraform init + $ terraform plan + $ terraform apply + ``` + + Note that this example will create resources. Resources can be destroyed with `terraform destroy`. + + ```hcl + {{ include "./main.tf" }} + ``` + +output: + file: README.md + mode: replace diff --git a/modules/terraform-aci-nd-interface-policy/examples/complete/README.md b/modules/terraform-aci-nd-interface-policy/examples/complete/README.md new file mode 100644 index 00000000..9267c37e --- /dev/null +++ b/modules/terraform-aci-nd-interface-policy/examples/complete/README.md @@ -0,0 +1,36 @@ + +# ND Interface Policy Example + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example will create resources. Resources can be destroyed with `terraform destroy`. + +```hcl +module "aci_nd_interface_policy" { + source = "netascode/nac-aci/aci//modules/terraform-aci-nd-interface-policy" + version = ">= 0.8.0" + + tenant = "ABC" + name = "ND-INTF-POL1" + description = "My Description" + controller_state = ["other-cfg"] + hop_limit = 32 + ns_tx_interval = 1000 + mtu = 9000 + retransmit_retry_count = 3 + nud_retransmit_base = 1 + nud_retransmit_interval = 2000 + nud_retransmit_count = 3 + route_advertise_interval = 600 + router_lifetime = 3600 + reachable_time = 0 + retransmit_timer = 0 +} +``` + \ No newline at end of file diff --git a/modules/terraform-aci-nd-interface-policy/examples/complete/main.tf b/modules/terraform-aci-nd-interface-policy/examples/complete/main.tf new file mode 100644 index 00000000..d8109ce0 --- /dev/null +++ b/modules/terraform-aci-nd-interface-policy/examples/complete/main.tf @@ -0,0 +1,20 @@ +module "aci_nd_interface_policy" { + source = "netascode/nac-aci/aci//modules/terraform-aci-nd-interface-policy" + version = ">= 0.8.0" + + tenant = "ABC" + name = "ND-INTF-POL1" + description = "My Description" + controller_state = ["other-cfg"] + hop_limit = 32 + ns_tx_interval = 1000 + mtu = 9000 + retransmit_retry_count = 3 + nud_retransmit_base = 1 + nud_retransmit_interval = 2000 + nud_retransmit_count = 3 + route_advertise_interval = 600 + router_lifetime = 3600 + reachable_time = 0 + retransmit_timer = 0 +} diff --git a/modules/terraform-aci-nd-interface-policy/examples/complete/versions.tf b/modules/terraform-aci-nd-interface-policy/examples/complete/versions.tf new file mode 100644 index 00000000..e8b775ae --- /dev/null +++ b/modules/terraform-aci-nd-interface-policy/examples/complete/versions.tf @@ -0,0 +1,11 @@ + +terraform { + required_version = ">= 1.0.0" + + required_providers { + aci = { + source = "CiscoDevNet/aci" + version = ">= 2.0.0" + } + } +} diff --git a/modules/terraform-aci-nd-interface-policy/main.tf b/modules/terraform-aci-nd-interface-policy/main.tf new file mode 100644 index 00000000..2b366ee2 --- /dev/null +++ b/modules/terraform-aci-nd-interface-policy/main.tf @@ -0,0 +1,20 @@ +resource "aci_rest_managed" "ndIfPol" { + dn = "uni/tn-${var.tenant}/ndifpol-${var.name}" + class_name = "ndIfPol" + content = { + name = var.name + descr = var.description + ctrl = join(",", var.controller_state) + hopLimit = var.hop_limit + nsIntvl = var.ns_tx_interval + mtu = var.mtu + nsRetries = var.retransmit_retry_count + nudRetryBase = var.nud_retransmit_base + nudRetryInterval = var.nud_retransmit_interval + nudRetryMaxAttempts = var.nud_retransmit_count + raIntvl = var.route_advertise_interval + raLifetime = var.router_lifetime + reachableTime = var.reachable_time + retransTimer = var.retransmit_timer + } +} \ No newline at end of file diff --git a/modules/terraform-aci-nd-interface-policy/outputs.tf b/modules/terraform-aci-nd-interface-policy/outputs.tf new file mode 100644 index 00000000..39d3f4b1 --- /dev/null +++ b/modules/terraform-aci-nd-interface-policy/outputs.tf @@ -0,0 +1,9 @@ +output "dn" { + value = aci_rest_managed.ndIfPol.id + description = "Distinguished name of `ndIfPol` object." +} + +output "name" { + value = aci_rest_managed.ndIfPol.content.name + description = "ND interface policy name." +} diff --git a/modules/terraform-aci-nd-interface-policy/variables.tf b/modules/terraform-aci-nd-interface-policy/variables.tf new file mode 100644 index 00000000..388b4a90 --- /dev/null +++ b/modules/terraform-aci-nd-interface-policy/variables.tf @@ -0,0 +1,163 @@ +variable "tenant" { + description = "Tenant name." + type = string + + validation { + condition = can(regex("^[a-zA-Z0-9_.-]{0,64}$", var.tenant)) + error_message = "Allowed characters: `a`-`z`, `A`-`Z`, `0`-`9`, `_`, `.`, `-`. Maximum characters: 64." + } +} +variable "name" { + description = "ND interface policy name." + type = string + + validation { + condition = can(regex("^[a-zA-Z0-9_.-]{0,64}$", var.name)) + error_message = "Allowed characters: `a`-`z`, `A`-`Z`, `0`-`9`, `_`, `.`, `-`. Maximum characters: 64." + } +} + +variable "description" { + description = "Description." + type = string + default = "" + + validation { + condition = can(regex("^[a-zA-Z0-9\\!#$%()*,-./:;@ _{|}~?&+]{0,128}$", var.description)) + error_message = "Allowed characters: `a`-`z`, `A`-`Z`, `0`-`9`, `\\`, `!`, `#`, `$`, `%`, `(`, `)`, `*`, `,`, `-`, `.`, `/`, `:`, `;`, `@`, ` `, `_`, `{`, `|`, }`, `~`, `?`, `&`, `+`. Maximum characters: 128." + } +} + +variable "controller_state" { + description = "Controller administrative state." + type = list(string) + default = [] + + validation { + condition = alltrue([ + for state in var.controller_state : contains(["managed-cfg", "other-cfg", "suppress-ra", "suppress-ra-mtu", "unsolicit-na-glean"], state) + ]) + error_message = "Allowed values are `managed-cfg`, `other-cfg`, `suppress-ra`, `suppress-ra-mtu`, or `unsolicit-na-glean`" + } +} + +variable "hop_limit" { + description = "Detection multiplier. Minimum value: 0. Maximum value: 255." + type = number + default = 64 + + validation { + condition = var.hop_limit >= 0 && var.hop_limit <= 255 + error_message = "Minimum value: 0. Maximum value: 255." + } +} + +variable "ns_tx_interval" { + description = "Neighbor solicitation transmit interval (msec). Minimum value: 1000. Maximum value: 3600000." + type = number + default = 1000 + + validation { + condition = var.ns_tx_interval >= 50 && var.ns_tx_interval <= 3600000 + error_message = "Minimum value: 1000. Maximum value: 360000." + } +} + +variable "mtu" { + description = "Maximum transmission unit. Minimum value: 1280. Maximum value: 9000." + type = number + default = 9000 + + validation { + condition = var.mtu >= 1280 && var.mtu <= 9000 + error_message = "Minimum value: 1280. Maximum value: 9000." + } +} + +variable "retransmit_retry_count" { + description = "Retransmission retry count. Minimum value: 1. Maximum value: 100." + type = number + default = 3 + + validation { + condition = var.retransmit_retry_count >= 1 && var.retransmit_retry_count <= 100 + error_message = "Minimum value: 1. Maximum value: 100." + } +} + +variable "nud_retransmit_base" { + description = "NUD retransmission base. Minimum value: 1. Maximum value: 3." + type = number + default = 1 + + validation { + condition = var.nud_retransmit_base >= 1 && var.nud_retransmit_base <= 3 + error_message = "Minimum value: 1. Maximum value: 3." + } +} + +variable "nud_retransmit_interval" { + description = "NUD retransmission interval (msec). Minimum value: 1000. Maximum value: 10000." + type = number + default = 1000 + + validation { + condition = var.nud_retransmit_interval >= 1000 && var.nud_retransmit_interval <= 10000 + error_message = "Minimum value: 1000. Maximum value: 10000." + } +} + +variable "nud_retransmit_count" { + description = "NUD retransmission count. Minimum value: 3. Maximum value: 10." + type = number + default = 3 + + validation { + condition = var.nud_retransmit_count >= 3 && var.nud_retransmit_count <= 10 + error_message = "Minimum value: 3. Maximum value: 10." + } +} + +variable "route_advertise_interval" { + description = "Route advertise interval. Minimum value: 4. Maximum value: 1800." + type = number + default = 600 + + validation { + condition = var.route_advertise_interval >= 4 && var.route_advertise_interval <= 1800 + error_message = "Minimum value: 4. Maximum value: 1800." + } +} + +variable "router_lifetime" { + description = "Router lifetime. Minimum value: 0. Maximum value: 9000." + type = number + default = 1800 + + validation { + condition = var.router_lifetime >= 0 && var.router_lifetime <= 9000 + error_message = "Minimum value: 0. Maximum value: 9000." + } +} + +variable "reachable_time" { + description = "Reachable time (msec). Minimum value: 0. Maximum value: 3600000." + type = number + default = 0 + + validation { + condition = var.reachable_time >= 0 && var.reachable_time <= 3600000 + error_message = "Minimum value: 0. Maximum value: 360000." + } +} + +variable "retransmit_timer" { + description = "Retransmit timer (msec). Minimum value: 0. Maximum value: 4294967295." + type = number + default = 0 + + validation { + condition = var.retransmit_timer >= 0 && var.retransmit_timer <= 4294967295 + error_message = "Minimum value: 0. Maximum value: 4294967295." + } +} \ No newline at end of file diff --git a/modules/terraform-aci-nd-interface-policy/versions.tf b/modules/terraform-aci-nd-interface-policy/versions.tf new file mode 100644 index 00000000..e8b775ae --- /dev/null +++ b/modules/terraform-aci-nd-interface-policy/versions.tf @@ -0,0 +1,11 @@ + +terraform { + required_version = ">= 1.0.0" + + required_providers { + aci = { + source = "CiscoDevNet/aci" + version = ">= 2.0.0" + } + } +}