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"
+ }
+ }
+}