diff --git a/README.md b/README.md
index 6d3ec6c..833d3dc 100644
--- a/README.md
+++ b/README.md
@@ -33,12 +33,15 @@ The following providers are used by this module:
The following resources are used by this module:
+- [azapi_resource.dapr_components](https://registry.terraform.io/providers/Azure/azapi/latest/docs/resources/resource) (resource)
+- [azapi_resource.storages](https://registry.terraform.io/providers/Azure/azapi/latest/docs/resources/resource) (resource)
- [azapi_resource.this_environment](https://registry.terraform.io/providers/Azure/azapi/latest/docs/resources/resource) (resource)
- [azurerm_management_lock.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_lock) (resource)
- [azurerm_monitor_diagnostic_setting.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_diagnostic_setting) (resource)
- [azurerm_resource_group_template_deployment.telemetry](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group_template_deployment) (resource)
- [azurerm_role_assignment.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) (resource)
- [random_id.telem](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) (resource)
+- [azapi_resource.this_environment](https://registry.terraform.io/providers/Azure/azapi/latest/docs/data-sources/resource) (data source)
- [azurerm_resource_group.parent](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) (data source)
@@ -86,6 +89,63 @@ Type: `string`
Default: `null`
+### [dapr\_components](#input\_dapr\_components)
+
+Description: - `component_type` - (Required) The Dapr Component Type. For example `state.azure.blobstorage`. Changing this forces a new resource to be created.
+- `ignore_errors` - (Optional) Should the Dapr sidecar to continue initialisation if the component fails to load. Defaults to `false`
+- `init_timeout` - (Optional) The timeout for component initialisation as a `ISO8601` formatted string. e.g. `5s`, `2h`, `1m`. Defaults to `5s`.
+- `secret_store_component` - (Optional) Name of a Dapr component to retrieve component secrets from.
+- `scopes` - (Optional) A list of scopes to which this component applies.
+- `version` - (Required) The version of the component.
+
+---
+`metadata` block supports the following:
+- `name` - (Required) The name of the Metadata configuration item.
+- `secret_name` - (Optional) The name of a secret specified in the `secrets` block that contains the value for this metadata configuration item.
+- `value` - (Optional) The value for this metadata configuration item.
+
+---
+`secret` block supports the following:
+- `name` - (Required) The Secret name.
+- `value` - (Required) The value for this secret.
+
+---
+`timeouts` block supports the following:
+- `create` - (Defaults to 30 minutes) Used when creating the Container App Environment Dapr Component.
+- `delete` - (Defaults to 30 minutes) Used when deleting the Container App Environment Dapr Component.
+- `read` - (Defaults to 5 minutes) Used when retrieving the Container App Environment Dapr Component.
+- `update` - (Defaults to 30 minutes) Used when updating the Container App Environment Dapr Component.
+
+Type:
+
+```hcl
+map(object({
+ component_type = string
+ ignore_errors = optional(bool, true)
+ init_timeout = optional(string)
+ secret_store_component = optional(string)
+ scopes = optional(list(string))
+ version = string
+ metadata = optional(list(object({
+ name = string
+ secret_name = optional(string)
+ value = optional(string)
+ })))
+ secret = optional(set(object({
+ name = string
+ value = string
+ })))
+ timeouts = optional(object({
+ create = optional(string)
+ delete = optional(string)
+ read = optional(string)
+ update = optional(string)
+ }))
+ }))
+```
+
+Default: `{}`
+
### [diagnostic\_settings](#input\_diagnostic\_settings)
Description: A map of diagnostic settings to create on the Key Vault. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time.
@@ -240,6 +300,39 @@ map(object({
Default: `{}`
+### [storages](#input\_storages)
+
+Description: - `access_key` - (Required) The Storage Account Access Key.
+- `access_mode` - (Required) The access mode to connect this storage to the Container App. Possible values include `ReadOnly` and `ReadWrite`. Changing this forces a new resource to be created.
+- `account_name` - (Required) The Azure Storage Account in which the Share to be used is located. Changing this forces a new resource to be created.
+- `share_name` - (Required) The name of the Azure Storage Share to use. Changing this forces a new resource to be created.
+
+---
+`timeouts` block supports the following:
+- `create` - (Defaults to 30 minutes) Used when creating the Container App Environment Storage.
+- `delete` - (Defaults to 30 minutes) Used when deleting the Container App Environment Storage.
+- `read` - (Defaults to 5 minutes) Used when retrieving the Container App Environment Storage.
+- `update` - (Defaults to 30 minutes) Used when updating the Container App Environment Storage.
+
+Type:
+
+```hcl
+map(object({
+ access_key = string
+ access_mode = string
+ account_name = string
+ share_name = string
+ timeouts = optional(object({
+ create = optional(string)
+ delete = optional(string)
+ read = optional(string)
+ update = optional(string)
+ }))
+ }))
+```
+
+Default: `{}`
+
### [tags](#input\_tags)
Description: (Optional) A mapping of tags to assign to the resource.
@@ -312,6 +405,10 @@ Default: `true`
The following outputs are exported:
+### [dapr\_components](#output\_dapr\_components)
+
+Description: A map of dapr components connected to this environment. The map key is the supplied input to var.storages. The map value is the azurerm-formatted version of the entire dapr\_components resource.
+
### [id](#output\_id)
Description: The ID of the resource.
@@ -324,6 +421,10 @@ Description: The name of the resource
Description: The Container Apps Managed Environment resource.
+### [storages](#output\_storages)
+
+Description: A map of storage shares connected to this environment. The map key is the supplied input to var.storages. The map value is the azurerm-formatted version of the entire storage shares resource.
+
## Modules
No modules.
diff --git a/avm b/avm
old mode 100644
new mode 100755
diff --git a/examples/dapr_component/README.md b/examples/dapr_component/README.md
new file mode 100644
index 0000000..2dcddcb
--- /dev/null
+++ b/examples/dapr_component/README.md
@@ -0,0 +1,117 @@
+
+# Default example
+
+This deploys the module with a environment-scoped dapr component.
+
+```hcl
+terraform {
+ required_version = ">= 1.3.0"
+ required_providers {
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = ">= 3.7.0, < 4.0.0"
+ }
+ }
+}
+
+provider "azurerm" {
+ skip_provider_registration = true
+ features {}
+}
+
+# This ensures we have unique CAF compliant names for our resources.
+module "naming" {
+ source = "Azure/naming/azurerm"
+ version = "0.4.0"
+}
+
+# This is required for resource modules
+resource "azurerm_resource_group" "this" {
+ name = module.naming.resource_group.name_unique
+ location = "australiaeast"
+}
+
+resource "azurerm_log_analytics_workspace" "this" {
+ name = module.naming.log_analytics_workspace.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+ location = azurerm_resource_group.this.location
+}
+
+module "managedenvironment" {
+ source = "../../"
+ # source = "Azure/avm-res-app-managedenvironment/azurerm"
+
+ name = module.naming.container_app_environment.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+
+ log_analytics_workspace_customer_id = azurerm_log_analytics_workspace.this.workspace_id
+ log_analytics_workspace_primary_shared_key = azurerm_log_analytics_workspace.this.primary_shared_key
+
+ dapr_components = {
+ "my-dapr-component" = {
+ component_type = "state.azure.blobstorage"
+ version = "v1"
+ }
+ }
+
+ # zone redundancy must be disabled unless we supply a subnet for vnet integration.
+ zone_redundancy_enabled = false
+}
+```
+
+
+## Requirements
+
+The following requirements are needed by this module:
+
+- [terraform](#requirement\_terraform) (>= 1.3.0)
+
+- [azurerm](#requirement\_azurerm) (>= 3.7.0, < 4.0.0)
+
+## Providers
+
+The following providers are used by this module:
+
+- [azurerm](#provider\_azurerm) (>= 3.7.0, < 4.0.0)
+
+## Resources
+
+The following resources are used by this module:
+
+- [azurerm_log_analytics_workspace.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/log_analytics_workspace) (resource)
+- [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) (resource)
+
+
+## Required Inputs
+
+No required inputs.
+
+## Optional Inputs
+
+No optional inputs.
+
+## Outputs
+
+No outputs.
+
+## Modules
+
+The following Modules are called:
+
+### [managedenvironment](#module\_managedenvironment)
+
+Source: ../../
+
+Version:
+
+### [naming](#module\_naming)
+
+Source: Azure/naming/azurerm
+
+Version: 0.4.0
+
+
+## Data Collection
+
+The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
+
\ No newline at end of file
diff --git a/examples/dapr_component/_footer.md b/examples/dapr_component/_footer.md
new file mode 100644
index 0000000..bc56bcb
--- /dev/null
+++ b/examples/dapr_component/_footer.md
@@ -0,0 +1,4 @@
+
+## Data Collection
+
+The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
diff --git a/examples/dapr_component/_header.md b/examples/dapr_component/_header.md
new file mode 100644
index 0000000..396e9dc
--- /dev/null
+++ b/examples/dapr_component/_header.md
@@ -0,0 +1,3 @@
+# Default example
+
+This deploys the module with a environment-scoped dapr component.
diff --git a/examples/dapr_component/main.tf b/examples/dapr_component/main.tf
new file mode 100644
index 0000000..b47f521
--- /dev/null
+++ b/examples/dapr_component/main.tf
@@ -0,0 +1,53 @@
+terraform {
+ required_version = ">= 1.3.0"
+ required_providers {
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = ">= 3.7.0, < 4.0.0"
+ }
+ }
+}
+
+provider "azurerm" {
+ skip_provider_registration = true
+ features {}
+}
+
+# This ensures we have unique CAF compliant names for our resources.
+module "naming" {
+ source = "Azure/naming/azurerm"
+ version = "0.4.0"
+}
+
+# This is required for resource modules
+resource "azurerm_resource_group" "this" {
+ name = module.naming.resource_group.name_unique
+ location = "australiaeast"
+}
+
+resource "azurerm_log_analytics_workspace" "this" {
+ name = module.naming.log_analytics_workspace.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+ location = azurerm_resource_group.this.location
+}
+
+module "managedenvironment" {
+ source = "../../"
+ # source = "Azure/avm-res-app-managedenvironment/azurerm"
+
+ name = module.naming.container_app_environment.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+
+ log_analytics_workspace_customer_id = azurerm_log_analytics_workspace.this.workspace_id
+ log_analytics_workspace_primary_shared_key = azurerm_log_analytics_workspace.this.primary_shared_key
+
+ dapr_components = {
+ "my-dapr-component" = {
+ component_type = "state.azure.blobstorage"
+ version = "v1"
+ }
+ }
+
+ # zone redundancy must be disabled unless we supply a subnet for vnet integration.
+ zone_redundancy_enabled = false
+}
diff --git a/examples/storage_share/README.md b/examples/storage_share/README.md
new file mode 100644
index 0000000..ae09047
--- /dev/null
+++ b/examples/storage_share/README.md
@@ -0,0 +1,135 @@
+
+# Default example
+
+This deploys the module with Container App Environment storage.
+
+```hcl
+terraform {
+ required_version = ">= 1.3.0"
+ required_providers {
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = ">= 3.7.0, < 4.0.0"
+ }
+ }
+}
+
+provider "azurerm" {
+ skip_provider_registration = true
+ features {}
+}
+
+# This ensures we have unique CAF compliant names for our resources.
+module "naming" {
+ source = "Azure/naming/azurerm"
+ version = "0.4.0"
+}
+
+# This is required for resource modules
+resource "azurerm_resource_group" "this" {
+ name = module.naming.resource_group.name_unique
+ location = "australiaeast"
+}
+
+resource "azurerm_log_analytics_workspace" "this" {
+ name = module.naming.log_analytics_workspace.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+ location = azurerm_resource_group.this.location
+}
+
+resource "azurerm_storage_account" "this" {
+ name = module.naming.storage_account.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+ location = azurerm_resource_group.this.location
+ account_tier = "Standard"
+ account_replication_type = "LRS"
+}
+
+resource "azurerm_storage_share" "this" {
+ name = "sharename"
+ storage_account_name = azurerm_storage_account.this.name
+ quota = 5
+}
+
+module "managedenvironment" {
+ source = "../../"
+ # source = "Azure/avm-res-app-managedenvironment/azurerm"
+
+ name = module.naming.container_app_environment.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+
+ log_analytics_workspace_customer_id = azurerm_log_analytics_workspace.this.workspace_id
+ log_analytics_workspace_primary_shared_key = azurerm_log_analytics_workspace.this.primary_shared_key
+
+ storages = {
+ "mycontainerappstorage" = {
+ account_name = azurerm_storage_account.this.name
+ share_name = azurerm_storage_share.this.name
+ access_key = azurerm_storage_account.this.primary_access_key
+ access_mode = "ReadOnly"
+ }
+ }
+
+ # zone redundancy must be disabled unless we supply a subnet for vnet integration.
+ zone_redundancy_enabled = false
+}
+```
+
+
+## Requirements
+
+The following requirements are needed by this module:
+
+- [terraform](#requirement\_terraform) (>= 1.3.0)
+
+- [azurerm](#requirement\_azurerm) (>= 3.7.0, < 4.0.0)
+
+## Providers
+
+The following providers are used by this module:
+
+- [azurerm](#provider\_azurerm) (>= 3.7.0, < 4.0.0)
+
+## Resources
+
+The following resources are used by this module:
+
+- [azurerm_log_analytics_workspace.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/log_analytics_workspace) (resource)
+- [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) (resource)
+- [azurerm_storage_account.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account) (resource)
+- [azurerm_storage_share.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_share) (resource)
+
+
+## Required Inputs
+
+No required inputs.
+
+## Optional Inputs
+
+No optional inputs.
+
+## Outputs
+
+No outputs.
+
+## Modules
+
+The following Modules are called:
+
+### [managedenvironment](#module\_managedenvironment)
+
+Source: ../../
+
+Version:
+
+### [naming](#module\_naming)
+
+Source: Azure/naming/azurerm
+
+Version: 0.4.0
+
+
+## Data Collection
+
+The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
+
\ No newline at end of file
diff --git a/examples/storage_share/_footer.md b/examples/storage_share/_footer.md
new file mode 100644
index 0000000..bc56bcb
--- /dev/null
+++ b/examples/storage_share/_footer.md
@@ -0,0 +1,4 @@
+
+## Data Collection
+
+The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.
diff --git a/examples/storage_share/_header.md b/examples/storage_share/_header.md
new file mode 100644
index 0000000..e5b8d0c
--- /dev/null
+++ b/examples/storage_share/_header.md
@@ -0,0 +1,3 @@
+# Default example
+
+This deploys the module with Container App Environment storage.
diff --git a/examples/storage_share/main.tf b/examples/storage_share/main.tf
new file mode 100644
index 0000000..9b147d6
--- /dev/null
+++ b/examples/storage_share/main.tf
@@ -0,0 +1,69 @@
+terraform {
+ required_version = ">= 1.3.0"
+ required_providers {
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = ">= 3.7.0, < 4.0.0"
+ }
+ }
+}
+
+provider "azurerm" {
+ skip_provider_registration = true
+ features {}
+}
+
+# This ensures we have unique CAF compliant names for our resources.
+module "naming" {
+ source = "Azure/naming/azurerm"
+ version = "0.4.0"
+}
+
+# This is required for resource modules
+resource "azurerm_resource_group" "this" {
+ name = module.naming.resource_group.name_unique
+ location = "australiaeast"
+}
+
+resource "azurerm_log_analytics_workspace" "this" {
+ name = module.naming.log_analytics_workspace.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+ location = azurerm_resource_group.this.location
+}
+
+resource "azurerm_storage_account" "this" {
+ name = module.naming.storage_account.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+ location = azurerm_resource_group.this.location
+ account_tier = "Standard"
+ account_replication_type = "LRS"
+}
+
+resource "azurerm_storage_share" "this" {
+ name = "sharename"
+ storage_account_name = azurerm_storage_account.this.name
+ quota = 5
+}
+
+module "managedenvironment" {
+ source = "../../"
+ # source = "Azure/avm-res-app-managedenvironment/azurerm"
+
+ name = module.naming.container_app_environment.name_unique
+ resource_group_name = azurerm_resource_group.this.name
+
+ log_analytics_workspace_customer_id = azurerm_log_analytics_workspace.this.workspace_id
+ log_analytics_workspace_primary_shared_key = azurerm_log_analytics_workspace.this.primary_shared_key
+
+ storages = {
+ "mycontainerappstorage" = {
+ account_name = azurerm_storage_account.this.name
+ share_name = azurerm_storage_share.this.name
+ access_key = azurerm_storage_account.this.primary_access_key
+ access_mode = "ReadOnly"
+ }
+ }
+
+ # zone redundancy must be disabled unless we supply a subnet for vnet integration.
+ zone_redundancy_enabled = false
+}
diff --git a/examples/workload_profile_internal/README.md b/examples/workload_profile_internal/README.md
index 9a0fce3..ebe4a2b 100644
--- a/examples/workload_profile_internal/README.md
+++ b/examples/workload_profile_internal/README.md
@@ -111,7 +111,11 @@ No optional inputs.
## Outputs
-No outputs.
+The following outputs are exported:
+
+### [app\_environment](#output\_app\_environment)
+
+Description: The outputs for the managed environment, this allows outputs to be inspected in the CI run.
## Modules
diff --git a/examples/workload_profile_internal/output.tf b/examples/workload_profile_internal/output.tf
new file mode 100644
index 0000000..fef74b2
--- /dev/null
+++ b/examples/workload_profile_internal/output.tf
@@ -0,0 +1,4 @@
+output "app_environment" {
+ description = "The outputs for the managed environment, this allows outputs to be inspected in the CI run."
+ value = module.managedenvironment.resource
+}
diff --git a/locals.telemetry.tf b/locals.telemetry.tf
index 45abc70..0e04de2 100644
--- a/locals.telemetry.tf
+++ b/locals.telemetry.tf
@@ -1,8 +1,14 @@
locals {
- # TODO: change this to the name of the module. See https://azure.github.io/Azure-Verified-Modules/specs/shared/#id-sfr3---category-telemetry---deploymentusage-telemetry
+ # This is the unique id AVM Terraform modules that is supplied by the AVM team.
+ # See https://azure.github.io/Azure-Verified-Modules/specs/shared/#id-sfr3---category-telemetry---deploymentusage-telemetry
+ telem_puid = "46d3xgtf"
+
module_name = "app-managedenvironment"
- # TODO: Change this. Should be either `res` or `ptn`
module_type = "res"
+
+ # This ensures we don't get errors if telemetry is disabled.
+ telem_random_hex = can(random_id.telem[0].hex) ? random_id.telem[0].hex : ""
+
# This constructs the ARM deployment name that is used for the telemetry.
# We shouldn't ever hit the 64 character limit but use substr just in case.
telem_arm_deployment_name = substr(
@@ -17,25 +23,21 @@ locals {
0,
64
)
+
# This is an empty ARM deployment template.
- telem_arm_template_content = < {
+ id = sv.id
+ access_mode = jsondecode(sv.body).properties.azureFile.accessMode
+ access_key = jsondecode(sv.body).properties.azureFile.accountKey
+ account_name = jsondecode(sv.body).properties.azureFile.accountName
+ share_name = jsondecode(sv.body).properties.azureFile.shareName
+ }
+ }
+
+ dapr_component_outputs = {
+ for dk, dv in azapi_resource.dapr_components :
+ dk => {
+ id = dv.id
+ component_type = jsondecode(dv.body).properties.componentType
+ ignore_errors = jsondecode(dv.body).properties.ignoreErrors
+ init_timeout = jsondecode(dv.body).properties.initTimeout
+ secret_store_component = jsondecode(dv.body).properties.secretStoreComponent
+ scopes = jsondecode(dv.body).properties.scopes
+ version = jsondecode(dv.body).properties.version
+ metadata = jsondecode(dv.body).properties.metadata != null ? [
+ for item in jsondecode(dv.body).properties.metadata : {
+ name = item.name
+ secret_name = item.secretRef
+ value = item.value
+ }
+ ] : null
+ secret = jsondecode(dv.body).properties.secrets != null ? [
+ for item in jsondecode(dv.body).properties.secrets : {
+ name = item.name
+ value = item.value
+ identity = item.identity
+ key_vault_secret_id = item.keyVaultUrl
+ }
+ ] : null
+ }
+ }
}
diff --git a/main.dapr_component.tf b/main.dapr_component.tf
new file mode 100644
index 0000000..e9ca389
--- /dev/null
+++ b/main.dapr_component.tf
@@ -0,0 +1,44 @@
+resource "azapi_resource" "dapr_components" {
+ for_each = var.dapr_components
+
+ type = "Microsoft.App/managedEnvironments/daprComponents@2023-05-01"
+ name = each.key
+ parent_id = azapi_resource.this_environment.id
+ body = jsonencode({
+ properties = {
+ componentType = each.value.component_type
+ ignoreErrors = each.value.ignore_errors
+ initTimeout = each.value.init_timeout
+ secretStoreComponent = each.value.secret_store_component
+ scopes = each.value.scopes
+ version = each.value.version
+
+ metadata = each.value.metadata != null ? [
+ for m in each.value.metadata : {
+ name = m.name
+ secretRef = m.secret_name
+ value = m.value
+ }
+ ] : null
+
+ secrets = each.value.secret != null ? [
+ for s in each.value.secret : {
+ identity = s.identity
+ keyVaultUrl = s.key_vault_secret_id
+ name = s.name
+ value = s.value
+ }
+ ] : null
+ }
+ })
+
+ dynamic "timeouts" {
+ for_each = each.value.timeouts == null ? [] : [each.value.timeouts]
+ content {
+ create = timeouts.value.create
+ delete = timeouts.value.delete
+ read = timeouts.value.read
+ update = timeouts.value.update
+ }
+ }
+}
diff --git a/main.storage.tf b/main.storage.tf
new file mode 100644
index 0000000..4b053cd
--- /dev/null
+++ b/main.storage.tf
@@ -0,0 +1,27 @@
+resource "azapi_resource" "storages" {
+ for_each = var.storages
+
+ type = "Microsoft.App/managedEnvironments/storages@2023-05-01"
+ name = each.key
+ parent_id = azapi_resource.this_environment.id
+ body = jsonencode({
+ properties = {
+ azureFile = {
+ accessMode = each.value.access_mode
+ accountKey = each.value.access_key
+ accountName = each.value.account_name
+ shareName = each.value.share_name
+ }
+ }
+ })
+
+ dynamic "timeouts" {
+ for_each = each.value.timeouts == null ? [] : [each.value.timeouts]
+ content {
+ create = timeouts.value.create
+ delete = timeouts.value.delete
+ read = timeouts.value.read
+ update = timeouts.value.update
+ }
+ }
+}
diff --git a/main.telemetry.tf b/main.telemetry.tf
index f15b62e..6d520a6 100644
--- a/main.telemetry.tf
+++ b/main.telemetry.tf
@@ -13,4 +13,6 @@ resource "azurerm_resource_group_template_deployment" "telemetry" {
name = local.telem_arm_deployment_name
resource_group_name = var.resource_group_name
template_content = local.telem_arm_template_content
+
+ tags = var.tags
}
diff --git a/main.tf b/main.tf
index 3120359..ad2ff90 100644
--- a/main.tf
+++ b/main.tf
@@ -54,6 +54,13 @@ resource "azapi_resource" "this_environment" {
}
}
+data "azapi_resource" "this_environment" {
+ type = "Microsoft.App/managedEnvironments@2023-05-01"
+ name = azapi_resource.this_environment.name
+ parent_id = data.azurerm_resource_group.parent.id
+ response_export_values = ["*"]
+}
+
resource "azurerm_management_lock" "this" {
count = var.lock.kind != "None" ? 1 : 0
diff --git a/outputs.tf b/outputs.tf
index c3a2894..7870624 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -1,8 +1,36 @@
# Module owners should include the full resource via a 'resource' output
# https://azure.github.io/Azure-Verified-Modules/specs/terraform/#id-tffr2---category-outputs---additional-terraform-outputs
+
output "resource" {
description = "The Container Apps Managed Environment resource."
- value = azapi_resource.this_environment
+ value = {
+ id = azapi_resource.this_environment.id
+ name = azapi_resource.this_environment.name
+ resource_group_name = data.azurerm_resource_group.parent.name
+ location = jsondecode(data.azapi_resource.this_environment.output).location
+
+ # outputs provided by the AzureRM provider
+ dapr_application_insights_connection_string = try(jsondecode(data.azapi_resource.this_environment.output).properties.daprAIConnectionString, null)
+ infrastructure_subnet_id = try(jsondecode(data.azapi_resource.this_environment.output).properties.vnetConfiguration.infrastructureSubnetId, null)
+ internal_load_balancer_enabled = try(jsondecode(data.azapi_resource.this_environment.output).properties.vnetConfiguration.internal, null)
+ log_analytics_workspace_id = try(jsondecode(data.azapi_resource.this_environment.output).properties.appLogsConfiguration.logAnalyticsConfiguration.customerId, null)
+ tags = try(azapi_resource.this_environment.tags, null)
+ workload_profiles = local.workload_profile_outputs
+ zone_redundancy_enabled = try(jsondecode(data.azapi_resource.this_environment.output).properties.zoneRedundant, null)
+
+ # outputs provided by the AzureRM provider known after apply
+ default_domain = jsondecode(data.azapi_resource.this_environment.output).properties.defaultDomain
+ docker_bridge_cidr = try(jsondecode(data.azapi_resource.this_environment.output).properties.vnetConfiguration.dockerBridgeCidr, null)
+ platform_reserved_cidr = try(jsondecode(data.azapi_resource.this_environment.output).properties.vnetConfiguration.platformReservedCidr, null)
+ platform_reserved_dns_ip_address = try(jsondecode(data.azapi_resource.this_environment.output).properties.vnetConfiguration.platformReservedDnsIP, null)
+ static_ip_address = jsondecode(data.azapi_resource.this_environment.output).properties.staticIp
+
+ # additional outputs not yet supported by the AzureRM provider
+ custom_domain_verification_id = try(jsondecode(data.azapi_resource.this_environment.output).properties.customDomainConfiguration.customDomainVerificationId, null)
+ dapr_azure_monitor_instrumentation_key = try(jsondecode(data.azapi_resource.this_environment.output).properties.daprAIInstrumentationKey, null)
+ infrastructure_resource_group = try(jsondecode(data.azapi_resource.this_environment.output).properties.infrastructureResourceGroup, null)
+ mtls_enabled = try(jsondecode(data.azapi_resource.this_environment.output).properties.peerAuthentication.mtls.enabled, false)
+ }
}
output "id" {
@@ -14,3 +42,13 @@ output "name" {
description = "The name of the resource"
value = azapi_resource.this_environment.name
}
+
+output "storages" {
+ description = "A map of storage shares connected to this environment. The map key is the supplied input to var.storages. The map value is the azurerm-formatted version of the entire storage shares resource."
+ value = local.storages_outputs
+}
+
+output "dapr_components" {
+ description = "A map of dapr components connected to this environment. The map key is the supplied input to var.storages. The map value is the azurerm-formatted version of the entire dapr_components resource."
+ value = local.dapr_component_outputs
+}
diff --git a/terraform.tf b/terraform.tf
index 4c9223d..4755f63 100644
--- a/terraform.tf
+++ b/terraform.tf
@@ -1,6 +1,10 @@
terraform {
required_version = ">= 1.5.0"
required_providers {
+ azapi = {
+ source = "Azure/azapi"
+ version = ">= 1.9.0, < 2.0"
+ }
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.71.0, < 4.0"
@@ -9,9 +13,5 @@ terraform {
source = "hashicorp/random"
version = ">= 3.5.0, < 4.0"
}
- azapi = {
- source = "Azure/azapi"
- version = ">= 1.9.0, < 2.0"
- }
}
}
diff --git a/variable.storage.tf b/variable.storage.tf
new file mode 100644
index 0000000..2ca1833
--- /dev/null
+++ b/variable.storage.tf
@@ -0,0 +1,29 @@
+variable "storages" {
+ type = map(object({
+ access_key = string
+ access_mode = string
+ account_name = string
+ share_name = string
+ timeouts = optional(object({
+ create = optional(string)
+ delete = optional(string)
+ read = optional(string)
+ update = optional(string)
+ }))
+ }))
+ default = {}
+ description = <<-EOT
+ - `access_key` - (Required) The Storage Account Access Key.
+ - `access_mode` - (Required) The access mode to connect this storage to the Container App. Possible values include `ReadOnly` and `ReadWrite`. Changing this forces a new resource to be created.
+ - `account_name` - (Required) The Azure Storage Account in which the Share to be used is located. Changing this forces a new resource to be created.
+ - `share_name` - (Required) The name of the Azure Storage Share to use. Changing this forces a new resource to be created.
+
+ ---
+ `timeouts` block supports the following:
+ - `create` - (Defaults to 30 minutes) Used when creating the Container App Environment Storage.
+ - `delete` - (Defaults to 30 minutes) Used when deleting the Container App Environment Storage.
+ - `read` - (Defaults to 5 minutes) Used when retrieving the Container App Environment Storage.
+ - `update` - (Defaults to 30 minutes) Used when updating the Container App Environment Storage.
+EOT
+ nullable = false
+}
diff --git a/variables.dapr_component.tf b/variables.dapr_component.tf
new file mode 100644
index 0000000..8ba3f5b
--- /dev/null
+++ b/variables.dapr_component.tf
@@ -0,0 +1,53 @@
+variable "dapr_components" {
+ type = map(object({
+ component_type = string
+ ignore_errors = optional(bool, true)
+ init_timeout = optional(string)
+ secret_store_component = optional(string)
+ scopes = optional(list(string))
+ version = string
+ metadata = optional(list(object({
+ name = string
+ secret_name = optional(string)
+ value = optional(string)
+ })))
+ secret = optional(set(object({
+ name = string
+ value = string
+ })))
+ timeouts = optional(object({
+ create = optional(string)
+ delete = optional(string)
+ read = optional(string)
+ update = optional(string)
+ }))
+ }))
+ default = {}
+ description = <<-EOT
+ - `component_type` - (Required) The Dapr Component Type. For example `state.azure.blobstorage`. Changing this forces a new resource to be created.
+ - `ignore_errors` - (Optional) Should the Dapr sidecar to continue initialisation if the component fails to load. Defaults to `false`
+ - `init_timeout` - (Optional) The timeout for component initialisation as a `ISO8601` formatted string. e.g. `5s`, `2h`, `1m`. Defaults to `5s`.
+ - `secret_store_component` - (Optional) Name of a Dapr component to retrieve component secrets from.
+ - `scopes` - (Optional) A list of scopes to which this component applies.
+ - `version` - (Required) The version of the component.
+
+ ---
+ `metadata` block supports the following:
+ - `name` - (Required) The name of the Metadata configuration item.
+ - `secret_name` - (Optional) The name of a secret specified in the `secrets` block that contains the value for this metadata configuration item.
+ - `value` - (Optional) The value for this metadata configuration item.
+
+ ---
+ `secret` block supports the following:
+ - `name` - (Required) The Secret name.
+ - `value` - (Required) The value for this secret.
+
+ ---
+ `timeouts` block supports the following:
+ - `create` - (Defaults to 30 minutes) Used when creating the Container App Environment Dapr Component.
+ - `delete` - (Defaults to 30 minutes) Used when deleting the Container App Environment Dapr Component.
+ - `read` - (Defaults to 5 minutes) Used when retrieving the Container App Environment Dapr Component.
+ - `update` - (Defaults to 30 minutes) Used when updating the Container App Environment Dapr Component.
+EOT
+ nullable = false
+}