This module manages the creation and configuration of an Azure Container App Environment. It supports network isolation, Azure Virtual Network integration, Dapr components,storage configuration, scaling, and secure communication for containerized applications.
- Managed Environment for Container Apps: Deploy and manage Azure Container Apps with minimal infrastructure overhead.
- Dapr Component Integration: Register and manage Dapr components for building stateful and stateless microservices.
- Networking and Security: Enable network isolation and Azure Virtual Network integration for secure connectivity and network policies.
- Storage Configuration: Manage Azure Storage shares integrated into the environment for persistent storage needs.
- Scalability and Monitoring: Support autoscaling of container workloads and integrate with monitoring solutions for enhanced insights.
- Flexible Configurations: Configure custom tags, Dapr settings, and other options to tailor the environment to your needs.
This example provisions an Azure Container App Environment with Dapr enabled, storage configured and custom tags for environment tracking.
resource "azurerm_resource_group" "rg" {
name = "rg-container-app-example"
location = "germanywestcentral"
}
resource "azurerm_user_assigned_identity" "this" {
location = azurerm_resource_group.rg.location
name = "example-user"
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_virtual_network" "this" {
name = "vnet-env"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
resource "azurerm_subnet" "this" {
name = "snet-env"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.this.name
address_prefixes = ["10.0.8.0/21"]
delegation {
name = "delegation-to-container-apps"
service_delegation {
name = "Microsoft.App/environments"
actions = [
"Microsoft.Network/virtualNetworks/subnets/action",
]
}
}
}
module "container_app_env" {
source = "../.."
name = "example-container-app-env"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
infrastructure_resource_group_name = "rg-infra-shared"
mutual_tls_enabled = true
tags = {
environment = "dev"
owner = "team-x"
}
identity = {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.this.id]
}
infrastructure_subnet_id = azurerm_subnet.this.id
internal_load_balancer_enabled = true
zone_redundancy_enabled = true
workload_profile = [
{
name = "custom-profile"
workload_profile_type = "D4"
minimum_count = 1
maximum_count = 3
}
]
container_app_environment_storage = {
"storage1" = {
name = "storage1"
account_name = "mystorageaccount"
access_key = "testAccessKey"
share_name = "fileshare1"
access_mode = "ReadWrite"
}
}
container_app_environment_dapr_component = {
"dapr-component1" = {
name = "dapr-component1"
component_type = "state.azure.blobstorage"
version = "v1"
ignore_errors = false
init_timeout = "30s"
scopes = ["myapp"]
metadata = [
{
name = "storageAccountName"
value = "mystorageaccount"
}
]
secret = [
{
name = "storageaccountkey"
value = "Test!SecretKey"
}
]
}
}
}| Name | Version |
|---|---|
| terraform | ~> 1.9.0 |
| azurerm | >= 4.0.0 |
| Name | Version |
|---|---|
| azurerm | >= 4.0.0 |
| Name | Type |
|---|---|
| azurerm_container_app_environment.this | resource |
| azurerm_container_app_environment_certificate.this | resource |
| azurerm_container_app_environment_custom_domain.this | resource |
| azurerm_container_app_environment_dapr_component.this | resource |
| azurerm_container_app_environment_storage.this | resource |
| azurerm_management_lock.this | resource |
| azurerm_role_assignment.this | resource |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| location | * location - (Required) Specifies the supported Azure location where the Container App Environment is to exist. Changing this forces a new resource to be created.Example Input: location = "westeurope" |
string |
n/a | yes |
| name | * name - (Required) The name of the Container Apps Managed Environment. Changing this forces a new resource to be created.Example Input: name = "container-app-environment-name" |
string |
n/a | yes |
| resource_group_name | * resource_group_name - (Required) The name of the resource group in which the Container App Environment is to be created. Changing this forces a new resource to be created.Example Input: resource_group_name = "container-app-environment-rg" |
string |
n/a | yes |
| container_app_environment_certificate | * container_app_environment_certificate - (Optional) A container_app_environment_certificate block as defined below.* name - (Required) The name of the Container Apps Environment Certificate. Changing this forces a new resource to be created.* container_app_environment_id - (Required) The Container App Managed Environment ID to configure this Certificate on. Changing this forces a new resource to be created.* certificate_blob_base64 - (Required) The Certificate Private Key as a base64 encoded PFX or PEM. Changing this forces a new resource to be created.* certificate_password - (Required) The password for the Certificate. Changing this forces a new resource to be created.Example Input: container_app_environment_certificate { |
map(object({ |
null |
no |
| container_app_environment_custom_domain | * container_app_environment_custom_domain - (Optional) A container_app_environment_custom_domain block as defined below.* container_app_environment_id - (Required) The ID of the Container Apps Managed Environment. Changing this forces a new resource to be created.* certificate_blob_base64 - (Required) The bundle of Private Key and Certificate for the Custom DNS Suffix as a base64 encoded PFX or PEM.* certificate_password - (Required) The password for the Certificate bundle.* dns_suffix - (Required) Custom DNS Suffix for the Container App Environment.Example Input: container_app_environment_custom_domain = { |
map(object({ |
null |
no |
| container_app_environment_dapr_component | * container_app_environment_dapr_component - (Optional) A container_app_environment_dapr_component block as defined below.* name - (Required) The name for this Dapr component. Changing this forces a new resource to be created.* container_app_environment_id - (Required) The ID of the Container App Managed Environment for this Dapr Component. Changing this forces a new resource to be created.* secret_store_component - (Optional) Name of a Dapr component to retrieve component secrets from.* component_type - (Required) The Dapr Component Type. For example state.azure.blobstorage. Changing this forces a new resource to be created.* version - (Required) The version of the component.* 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.* scopes - (Optional) A list of scopes to which this component applies.~> Note: See the official docs for more information at https://learn.microsoft.com/en-us/azure/container-apps/dapr-overview?tabs=bicep1%2Cyaml#component-scopes * metadata - (Optional) A metadata block as defined below.* 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 - (Optional) A secret block as defined below.* name - (Required) The Secret name.* value - (Required) The value for this secret.Example Input: container_app_environment_dapr_component = { |
map(object({ |
null |
no |
| container_app_environment_storage | * container_app_environment_storage - (Optional) A container_app_environment_storage block as defined below.* name - (Required) The name for this Container App Environment Storage. Changing this forces a new resource to be created.* container_app_environment_id - (Required) The ID of the Container App Environment to which this storage belongs. 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.* access_key - (Required) The Storage Account Access Key.* share_name - (Required) The name of the Azure Storage Share to use. Changing this forces a new resource to be created.* 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.* nfs_server_url - (Optional) The NFS server to use for the Azure File Share, the format will be yourstorageaccountname.file.core.windows.net. Changing this forces a new resource to be created.Example Input: container_app_environment_storage = { |
map(object({ |
null |
no |
| dapr_application_insights_connection_string | * dapr_application_insights_connection_string - (Optional) Application Insights connection string used by Dapr to export Service to Service communication telemetry. Changing this forces a new resource to be created.Example Input: dapr_application_insights_connection_string = "InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://.applicationinsights.azure.com/" |
string |
null |
no |
| identity | * identity - (Optional) An identity block as detailed below.* system_assigned - (Required) The type of managed identity to assign. Possible values are SystemAssigned, UserAssigned, and SystemAssigned, UserAssigned (to enable both).* identity_ids - (Optional) - A list of one or more Resource IDs for User Assigned Managed identities to assign. Required when type is set to UserAssigned or SystemAssigned, UserAssigned.Example Inputs: managed_identities = { |
object({ |
null |
no |
| infrastructure_resource_group_name | * infrastructure_resource_group_name - (Optional) Name of the platform-managed resource group created for the Managed Environment to host infrastructure resources. Changing this forces a new resource to be created.~> Note: Only valid if a workload_profile is specified. If infrastructure_subnet_id is specified, this resource group will be created in the same subscription as infrastructure_subnet_id.Example Input: infrastructure_resource_group_name = "rg-platform-managed-infrastructure" |
string |
null |
no |
| infrastructure_subnet_id | * infrastructure_subnet_id - (Optional) The existing Subnet to use for the Container Apps Control Plane. Changing this forces a new resource to be created.~> Note: The Subnet must have a /21 or larger address space.Example Input: infrastructure_subnet_id = "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rg-networking/providers/Microsoft.Network/virtualNetworks/vnet-main/subnets/snet-container-apps-control-plane" |
string |
null |
no |
| internal_load_balancer_enabled | * internal_load_balancer_enabled - (Optional) Should the Container Environment operate in Internal Load Balancing Mode? Defaults to false. Changing this forces a new resource to be created.~> Note: can only be set to true if infrastructure_subnet_id is specified.Example Input: internal_load_balancer_enabled = false |
bool |
null |
no |
| lock | * lock - (Optional) A lock block as defined below.* kind - (Required) The type of lock. Possible values are \"CanNotDelete\" and \"ReadOnly\".* name - (Optional) The name of the lock. If not specified, a name will be generated based on the kind value. Changing this forces the creation of a new resource.Example Input: lock = { |
object({ |
null |
no |
| log_analytics_workspace_id | * log_analytics_workspace_id - (Optional) The ID for the Log Analytics Workspace to link this Container Apps Managed Environment to.~> Note: required if logs_destination is set to log-analytics. Cannot be set if logs_destination is set to azure-monitor.Example Input: log_analytics_workspace_id = "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/rg-monitoring/providers/Microsoft.OperationalInsights/workspaces/workspace-name" |
string |
null |
no |
| logs_destination | * logs_destination -(Optional) Where the application logs will be saved for this Container Apps Managed Environment. Possible values include log-analytics and azure-monitor. Omitting this value will result in logs being streamed only.Example Input: logs_destination = "log-analytics" |
string |
null |
no |
| mutual_tls_enabled | * mutual_tls_enabled - (Optional) Should mutual transport layer security (mTLS) be enabled? Defaults to false.~> Note: This feature is in public preview. Enabling mTLS for your applications may increase response latency and reduce maximum throughput in high-load scenarios. Example Input: peer_authentication_enabled = false |
bool |
false |
no |
| role_assignments | * role_assignments - (Optional) A role_assignments block as defined below.* role_definition_id_or_name - The ID or name of the role definition to assign to the principal.* principal_id - The ID of the principal to assign the role to.* description - (Optional) The description of the role assignment.* skip_service_principal_aad_check - (Optional) If set to true, skips the Azure Active Directory check for the service principal in the tenant. Defaults to false.* condition - (Optional) The condition which will be used to scope the role assignment.* condition_version - (Optional) The version of the condition syntax. Leave as null if you are not using a condition, if you are then valid values are '2.0'.* delegated_managed_identity_resource_id - (Optional) The delegated Azure Resource Id which contains a Managed Identity. Changing this forces a new resource to be created. This field is only used in cross-tenant scenario.* principal_type - (Optional) The type of the principal_id. Possible values are User, Group and ServicePrincipal. It is necessary to explicitly set this attribute when creating role assignments if the principal creating the assignment is constrained by ABAC rules that filters on the PrincipalType attribute.~> Note: only set skip_service_principal_aad_check to true if you are assigning a role to a service principal.Example Input: role_assignments = { |
map(object({ |
null |
no |
| tags | * tags - (Optional) A map of tags to associate with the network and subnets.Example Input: tags = { |
map(string) |
null |
no |
| timeouts | * timeouts - (Optional) A timeouts block as defined below.* create - (Defaults to 30 minutes) Used when creating the Container App Environment.* delete - (Defaults to 30 minutes) Used when deleting the Container App Environment.* read - (Defaults to 5 minutes) Used when retrieving the Container App Environment.* update -(Defaults to 30 minutes) Used when updating the Container App Environment.Example Input: timeouts = { |
object({ |
null |
no |
| workload_profile | * workload_profile - (Optional) A workload_profile block as defined below.* name - (Required) The name of the workload profile.* workload_profile_type - (Required) Workload profile type for the workloads to run on. Possible values include Consumption, D4, D8, D16, D32, E4, E8, E16 and E32.~> Note: A Consumption type must have a name of Consumption and an environment may only have one Consumption Workload Profile.~> Note: Defining a Consumption profile is optional, however, Environments created without an initial Workload Profile cannot have them added at a later time and must be recreated. Similarly, an environment created with Profiles must always have at least one defined Profile, removing all profiles will force a recreation of the resource.* maximum_count - (Required) The maximum number of instances of workload profile that can be deployed in the Container App Environment.* minimum_count - (Required) The minimum number of instances of workload profile that can be deployed in the Container App Environment.Example Input: workload_profile = [ |
list(object({ |
null |
no |
| zone_redundancy_enabled | * zone_redundancy_enabled - (Optional) Should the Container App Environment be created with Zone Redundancy enabled? Defaults to false. Changing this forces a new resource to be created.~> Note: can only be set to true if infrastructure_subnet_id is specified.Example Input: zone_redundancy_enabled = false |
bool |
false |
no |
| Name | Description |
|---|---|
| container_app_env | * name - The name of the Container Apps Managed Environment.* resource_group_name - The name of the Resource Group where this Container App Environment exists.* location - The Azure Location where this Container App Environment exists.* dapr_application_insights_connection_string - Application Insights connection string used by Dapr to export Service to Service communication telemetry.* infrastructure_resource_group_name - Name of the platform-managed resource group created for the Managed Environment to host infrastructure resources.~> Note: Only valid if a workload_profile is specified. If infrastructure_subnet_id is specified, this resource group will be created in the same subscription as infrastructure_subnet_id.* infrastructure_subnet_id - The existing Subnet to use for the Container Apps Control Plane.~> Note: The Subnet must have a /21 or larger address space.* internal_load_balancer_enabled - Should the Container Environment operate in Internal Load Balancing Mode?~> Note: can only be set to true if infrastructure_subnet_id is specified.* zone_redundancy_enabled - Should the Container App Environment be created with Zone Redundancy enabled?~> Note: can only be set to true if infrastructure_subnet_id is specified.* log_analytics_workspace_id - The ID for the Log Analytics Workspace to link this Container Apps Managed Environment to.~> Note: required if logs_destination is set to log-analytics. Cannot be set if logs_destination is set to azure-monitor.* logs_destination - Where the application logs will be saved for this Container Apps Managed Environment. Possible values include log-analytics and azure-monitor.* workload_profile - A workload_profile block as defined below.* name - The name of the workload profile.* workload_profile_type - Workload profile type for the workloads to run on. Possible values include Consumption, D4, D8, D16, D32, E4, E8, E16 and E32.~> Note: A Consumption type must have a name of Consumption and an environment may only have one Consumption Workload Profile.~> Note: Defining a Consumption profile is optional, however, Environments created without an initial Workload Profile cannot have them added at a later time and must be recreated. Similarly, an environment created with Profiles must always have at least one defined Profile, removing all profiles will force a recreation of the resource.* maximum_count - The maximum number of instances of workload profile that can be deployed in the Container App Environment.* minimum_count - The minimum number of instances of workload profile that can be deployed in the Container App Environment.* mutual_tls_enabled - Should mutual transport layer security (mTLS) be enabled? Defaults to false.~> Note: This feature is in public preview. Enabling mTLS for your applications may increase response latency and reduce maximum throughput in high-load scenarios. * tags - A map of tags to associate with the network and subnets.* container_app_environment_custom_domain - A container_app_environment_custom_domain block as defined below.* container_app_environment_id - The ID of the Container Apps Managed Environment.* certificate_blob_base64 - The bundle of Private Key and Certificate for the Custom DNS Suffix as a base64 encoded PFX or PEM.* certificate_password - The password for the Certificate bundle.* dns_suffix - Custom DNS Suffix for the Container App Environment.* container_app_environment_certificate - A container_app_environment_certificate block as defined below.* name - The name of the Container Apps Environment Certificate.* container_app_environment_id - The Container App Managed Environment ID to configure this Certificate on.* certificate_blob_base64 - The Certificate Private Key as a base64 encoded PFX or PEM.* certificate_password - The password for the Certificate.* lock - A lock block as defined below.* kind - The type of lock. Possible values are \"CanNotDelete\" and \"ReadOnly\".* name - The name of the lock. If not specified, a name will be generated based on the kind value.* role_assignments - A role_assignments block as defined below.* role_definition_id_or_name - The ID or name of the role definition to assign to the principal.* principal_id - ID of the principal to assign the role to.* description - The description of the role assignment.* skip_service_principal_aad_check - If set to true, skips the Azure Active Directory check for the service principal in the tenant. Defaults to false.* condition - The condition which will be used to scope the role assignment.* condition_version - The version of the condition syntax. Leave as null if you are not using a condition, if you are then valid values are '2.0'.* delegated_managed_identity_resource_id - The delegated Azure Resource Id which contains a Managed Identity. This field is only used in cross-tenant scenario.* principal_type - The type of the principal_id. Possible values are User, Group and ServicePrincipal. It is necessary to explicitly set this attribute when creating role assignments if the principal creating the assignment is constrained by ABAC rules that filters on the PrincipalType attribute.~> Note: only set skip_service_principal_aad_check to true if you are assigning a role to a service principal.* timeouts - A timeouts block as defined below.* create - (Defaults to 30 minutes) Used when creating the Container App.* delete - (Defaults to 30 minutes) Used when deleting the Container App.* read - (Defaults to 5 minutes) Used when retrieving the Container App.* update -(Defaults to 30 minutes) Used when updating the Container App Environment Dapr Component.Example output: output "name" { |
| dapr_components | * name - The name for this Dapr component.* container_app_environment_id - The ID of the Container App Managed Environment for this Dapr Component.* secret_store_component - Name of a Dapr component to retrieve component secrets from.* component_type - The Dapr Component Type. For example state.azure.blobstorage.* version - The version of the component.* ignore_errors - Should the Dapr sidecar to continue initialisation if the component fails to load. Defaults to false* init_timeout - The timeout for component initialisation as a ISO8601 formatted string. e.g. 5s, 2h, 1m. Defaults to 5s.* scopes - A list of scopes to which this component applies.* metadata - A metadata block as defined below.* name - The name of the Metadata configuration item.* secret_name - The name of a secret specified in the secrets block that contains the value for this metadata configuration item.* value - The value for this metadata configuration item.* secret - A secret block as defined below.* name - The Secret name.* value - The value for this secret.Example output: output "dapr_components" { |
| storage | * name - The name for this Container App Environment Storage.* container_app_environment_id - The ID of the Container App Environment to which this storage belongs.* account_name - The Azure Storage Account in which the Share to be used is located.* access_key - The Storage Account Access Key.* share_name - The name of the Azure Storage Share to use.* access_mode - The access mode to connect this storage to the Container App. Possible values include ReadOnly and ReadWrite.Example output: output "storage" { |
No modules.
For more details about Azure Container Apps and configuring managed environments, refer to the Azure Container Apps documentation. This module is designed to manage an Azure Container App Environment, a managed environment that enables deploying and managing containerized applications and Dapr components without needing direct infrastructure oversight.
- AzureRM Terraform Provider Documentation
- Azure Container Apps Overview
- Dapr for Azure Container Apps
- Ensure container_app_environment_id matches the intended resource group and region for consistency.
- Enable vnet_integration only when virtual network connectivity is required for secure communication.
- Use dapr_enabled to support microservices with state management, pub/sub, or secure service-to-service communication.
- Regularly monitor and validate environment settings, including networking, storage, and monitoring configurations, for optimal performance and security.
- Apply least privilege principles by restricting network and role assignments to the minimum necessary.
- Organize Dapr components, storage, and network resources efficiently to reduce deployment time and complexity.
- Validate your Terraform configuration to ensure the Container App Environment and related resources are correctly created and integrated.
This module is licensed under the MIT License. See the LICENSE file for more details.