diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2356dc1e..b4ec5558 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -301,6 +301,10 @@ repos: args: ["./modules/terraform-aci-imported-contract"] - id: terraform-docs-system args: ["./modules/terraform-aci-imported-contract/examples/complete"] + - id: terraform-docs-system + args: ["./modules/terraform-aci-imported-l4l7-device"] + - id: terraform-docs-system + args: ["./modules/terraform-aci-imported-l4l7-device/examples/complete"] - id: terraform-docs-system args: ["./modules/terraform-aci-inband-endpoint-group"] - id: terraform-docs-system diff --git a/CHANGELOG.md b/CHANGELOG.md index f2b4a0f6..558f22b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Make L3 PBR destination MAC optional - Add `apic_include` option to `port_tracking` configuration - Add support for Radius Provider +- Add support for imported L4L7 devices ## 0.8.0 diff --git a/README.md b/README.md index 7197f369..3f0299fb 100644 --- a/README.md +++ b/README.md @@ -221,7 +221,7 @@ Additional example repositories: | [aci\_health\_score\_evaluation\_policy](#module\_aci\_health\_score\_evaluation\_policy) | ./modules/terraform-aci-health-score-evaluation-policy | n/a | | [aci\_igmp\_interface\_policy](#module\_aci\_igmp\_interface\_policy) | ./modules/terraform-aci-igmp-interface-policy | n/a | | [aci\_igmp\_snooping\_policy](#module\_aci\_igmp\_snooping\_policy) | ./modules/terraform-aci-igmp-snooping-policy | n/a | -| [aci\_imported\_contract](#module\_aci\_imported\_contract) | ./modules/terraform-aci-imported-contract | n/a | +| [aci\_imported\_contract](#module\_aci\_imported\_contract) | ./modules/terraform-aci-imported-l4l7-device | n/a | | [aci\_inband\_endpoint\_group](#module\_aci\_inband\_endpoint\_group) | ./modules/terraform-aci-inband-endpoint-group | n/a | | [aci\_inband\_node\_address](#module\_aci\_inband\_node\_address) | ./modules/terraform-aci-inband-node-address | n/a | | [aci\_infra\_dscp\_translation\_policy](#module\_aci\_infra\_dscp\_translation\_policy) | ./modules/terraform-aci-infra-dscp-translation-policy | n/a | diff --git a/aci_tenants.tf b/aci_tenants.tf index 13a070ff..4c89772d 100644 --- a/aci_tenants.tf +++ b/aci_tenants.tf @@ -2736,6 +2736,35 @@ module "aci_l4l7_device" { ] } +locals { + imported_l4l7_devices = flatten([ + for tenant in local.tenants : [ + for device in try(tenant.services.imported_l4l7_devices, []) : { + key = format("%s/%s", tenant.name, device.name) + tenant = tenant.name + source_tenant = device.tenant + source_device = "${device.name}${local.defaults.apic.tenants.services.l4l7_devices.name_suffix}" + description = try(device.description, "") + } + ] + ]) +} + +module "aci_imported_contract" { + source = "./modules/terraform-aci-imported-l4l7-device" + + for_each = { for device in local.imported_l4l7_devices : device.key => device if local.modules.aci_imported_l4l7_device && var.manage_tenants } + tenant = each.value.tenant + source_tenant = each.value.source_tenant + source_device = each.value.source_device + description = each.value.description + + depends_on = [ + module.aci_tenant, + ] +} + + locals { redirect_policies = flatten([ for tenant in local.tenants : [ diff --git a/defaults/modules.yaml b/defaults/modules.yaml index 173879db..4e096815 100644 --- a/defaults/modules.yaml +++ b/defaults/modules.yaml @@ -71,6 +71,7 @@ modules: aci_igmp_interface_policy: true aci_igmp_snooping_policy: true aci_imported_contract: true + aci_imported_l4l7_device: true aci_inband_endpoint_group: true aci_inband_node_address: true aci_infra_dscp_translation_policy: true diff --git a/modules/terraform-aci-imported-l4l7-device/.terraform-docs.yml b/modules/terraform-aci-imported-l4l7-device/.terraform-docs.yml new file mode 100644 index 00000000..a8694184 --- /dev/null +++ b/modules/terraform-aci-imported-l4l7-device/.terraform-docs.yml @@ -0,0 +1,34 @@ +version: '>= 0.14.0' + +formatter: markdown table + +content: |- + # Terraform ACI Imported L4L7 Device Module + + ACI Imported L4L7 Device + + Location in GUI: + `Tenants` » `XXX` » `Services` » `L4-L7` » `Imported Devices` + + ## 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-imported-l4l7-device/README.md b/modules/terraform-aci-imported-l4l7-device/README.md new file mode 100644 index 00000000..7469401f --- /dev/null +++ b/modules/terraform-aci-imported-l4l7-device/README.md @@ -0,0 +1,56 @@ + +# Terraform ACI Imported L4L7 Device Module + +ACI Imported L4L7 Device + +Location in GUI: +`Tenants` » `XXX` » `Services` » `L4-L7` » `Imported Devices` + +## Examples + +```hcl +module "aci_imported_l4l7_device" { + source = "netascode/nac-aci/aci//modules/terraform-aci-imported-l4l7-device" + version = ">= 0.8.1" + + tenant = "ABC" + source_tenant = "DEF" + source_device = "DEV1" + description = "My imported device" +} +``` + +## 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 | +| [source\_tenant](#input\_source\_tenant) | Source device tenant name. | `string` | n/a | yes | +| [source\_device](#input\_source\_device) | L4L7 device name to be imported. | `string` | n/a | yes | +| [description](#input\_description) | Imported device description. | `string` | `""` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [dn](#output\_dn) | Distinguished name of `vnsLDevIf` object. | + +## Resources + +| Name | Type | +|------|------| +| [aci_rest_managed.vnsLDevIf](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-imported-l4l7-device/examples/complete/.terraform-docs.yml b/modules/terraform-aci-imported-l4l7-device/examples/complete/.terraform-docs.yml new file mode 100644 index 00000000..525f4e90 --- /dev/null +++ b/modules/terraform-aci-imported-l4l7-device/examples/complete/.terraform-docs.yml @@ -0,0 +1,24 @@ +version: '>= 0.14.0' + +formatter: markdown table + +content: |- + # Imported L4L7 Device 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-imported-l4l7-device/examples/complete/README.md b/modules/terraform-aci-imported-l4l7-device/examples/complete/README.md new file mode 100644 index 00000000..80608308 --- /dev/null +++ b/modules/terraform-aci-imported-l4l7-device/examples/complete/README.md @@ -0,0 +1,25 @@ + +# Imported L4L7 Device 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_imported_l4l7_device" { + source = "netascode/nac-aci/aci//modules/terraform-aci-imported-l4l7-device" + version = ">= 0.8.1" + + tenant = "ABC" + source_tenant = "DEF" + source_device = "DEV1" + description = "My imported device" +} +``` + \ No newline at end of file diff --git a/modules/terraform-aci-imported-l4l7-device/examples/complete/main.tf b/modules/terraform-aci-imported-l4l7-device/examples/complete/main.tf new file mode 100644 index 00000000..56714dbf --- /dev/null +++ b/modules/terraform-aci-imported-l4l7-device/examples/complete/main.tf @@ -0,0 +1,9 @@ +module "aci_imported_l4l7_device" { + source = "netascode/nac-aci/aci//modules/terraform-aci-imported-l4l7-device" + version = ">= 0.8.1" + + tenant = "ABC" + source_tenant = "DEF" + source_device = "DEV1" + description = "My imported device" +} diff --git a/modules/terraform-aci-imported-l4l7-device/examples/complete/versions.tf b/modules/terraform-aci-imported-l4l7-device/examples/complete/versions.tf new file mode 100644 index 00000000..e8b775ae --- /dev/null +++ b/modules/terraform-aci-imported-l4l7-device/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-imported-l4l7-device/main.tf b/modules/terraform-aci-imported-l4l7-device/main.tf new file mode 100644 index 00000000..c223aedc --- /dev/null +++ b/modules/terraform-aci-imported-l4l7-device/main.tf @@ -0,0 +1,8 @@ +resource "aci_rest_managed" "vnsLDevIf" { + dn = "uni/tn-${var.tenant}/lDevIf-[uni/tn-${var.source_tenant}/lDevVip-${var.source_device}]" + class_name = "vnsLDevIf" + content = { + ldev = "uni/tn-${var.source_tenant}/lDevVip-${var.source_device}]" + description = var.description + } +} diff --git a/modules/terraform-aci-imported-l4l7-device/outputs.tf b/modules/terraform-aci-imported-l4l7-device/outputs.tf new file mode 100644 index 00000000..a64a20c4 --- /dev/null +++ b/modules/terraform-aci-imported-l4l7-device/outputs.tf @@ -0,0 +1,4 @@ +output "dn" { + value = aci_rest_managed.vnsLDevIf.id + description = "Distinguished name of `vnsLDevIf` object." +} diff --git a/modules/terraform-aci-imported-l4l7-device/variables.tf b/modules/terraform-aci-imported-l4l7-device/variables.tf new file mode 100644 index 00000000..898c4bec --- /dev/null +++ b/modules/terraform-aci-imported-l4l7-device/variables.tf @@ -0,0 +1,40 @@ +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 "source_tenant" { + description = "Source device tenant name." + type = string + + validation { + condition = can(regex("^[a-zA-Z0-9_.-]{0,64}$", var.source_tenant)) + error_message = "Allowed characters: `a`-`z`, `A`-`Z`, `0`-`9`, `_`, `.`, `-`. Maximum characters: 64." + } +} + +variable "source_device" { + description = "L4L7 device name to be imported." + 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 = "Imported device 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." + } +} diff --git a/modules/terraform-aci-imported-l4l7-device/versions.tf b/modules/terraform-aci-imported-l4l7-device/versions.tf new file mode 100644 index 00000000..e8b775ae --- /dev/null +++ b/modules/terraform-aci-imported-l4l7-device/versions.tf @@ -0,0 +1,11 @@ + +terraform { + required_version = ">= 1.0.0" + + required_providers { + aci = { + source = "CiscoDevNet/aci" + version = ">= 2.0.0" + } + } +}