Skip to content

This module manages Azure Container Apps and Jobs, enabling containerized tasks such as event-driven, scheduled, and manual jobs. It supports autoscaling, secure networking, and advanced configurations for microservices and serverless workloads.

License

Notifications You must be signed in to change notification settings

CloudAstro/terraform-azurerm-container-apps

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Azure Container Apps and Jobs Terraform Module

Changelog Notice MIT License OpenTofu Registry

This module manages Azure Container Apps and Jobs, enabling containerized tasks such as event-driven, scheduled, and manual jobs. It supports autoscaling, secure networking, and advanced configurations for microservices and serverless workloads.

Features

  • Orchestration: Built on Kubernetes and KEDA (Kubernetes Event-Driven Autoscaling) to manage complex apps and scale containers based on events.
  • Scale-to-Zero: Automatically scales to zero when not in use, cutting costs for low-traffic or event-driven apps.
  • Traffic Splitting: Supports routing traffic between multiple service revisions for canary deployments and A/B testing.
  • Environment Integration: Supports integration with managed APIs and Dapr (Distributed Application Runtime) for streamlined microservices communication in distributed systems.

Example Usage

This example demonstrates how to provision an Azure Container App with customized settings for scaling, networking, and secure access management.

resource "azurerm_resource_group" "ca-rg" {
  name     = "rg-container-app-example"
  location = "germanywestcentral"
}

resource "azurerm_user_assigned_identity" "this" {
  location            = azurerm_resource_group.ca-rg.location
  name                = "example-user"
  resource_group_name = azurerm_resource_group.ca-rg.name
}

module "ca-environment" {
  source = "git@ssh.dev.azure.com:v3/DevOpsCloudAstro/ca-terraform-modules/azure//tf-azurerm-container-app-environment"

  name                = "ca-env-dev"
  location            = azurerm_resource_group.ca-rg.location
  resource_group_name = azurerm_resource_group.ca-rg.name
  workload_profile = [
    {
      name                  = "Consumption"
      workload_profile_type = "Consumption"
    }
  ]
}

##### Container Apps Example #####

module "container_app" {
  source = "../../"

  container_type               = "app"
  name                         = "example-container-app"
  resource_group_name          = azurerm_resource_group.ca-rg.name
  container_app_environment_id = module.ca-environment.resource.id
  workload_profile_name        = "Consumption"
  revision_mode                = "Single"

  tags = {
    environment = "demo"
  }

  identity = {
    type         = "UserAssigned"
    identity_ids = [azurerm_user_assigned_identity.this.id]
  }

  template = {
    max_replicas                     = 2
    min_replicas                     = 1
    revision_suffix                  = "v1"
    termination_grace_period_seconds = 30

    container = {
      app = {
        name    = "web"
        image   = "mcr.microsoft.com/azuredocs/containerapps-helloworld:latest"
        cpu     = 0.5
        memory  = "1.0Gi"
        command = ["/bin/sh"]
        args    = ["-c", "echo Hello from Container App && sleep 3600"]
        env = [
          {
            name  = "ENVIRONMENT"
            value = "prod"
          }
        ]
        liveness_probe = [
          {
            path                    = "/health"
            port                    = 80
            interval_seconds        = 10
            initial_delay           = 5
            failure_count_threshold = 3
            timeout                 = 2
            host                    = "localhost"
            transport               = "HTTP"
            header = [
              {
                name  = "X-Probe-Check"
                value = "true"
              }

            ]
          }
        ]

        readiness_probe = [
          {
            path                    = "/ready"
            port                    = 80
            interval_seconds        = 5
            initial_delay           = 3
            failure_count_threshold = 3
            success_count_threshold = 1
            timeout                 = 2
            host                    = "localhost"
            transport               = "TCP"
            header = [
              {
                name  = "X-Ready-Check"
                value = "true"
              }
            ]
          }
        ]

        startup_probe = [
          {
            path                    = "/startup"
            port                    = 80
            interval_seconds        = 10
            initial_delay           = 5
            failure_count_threshold = 30
            timeout                 = 2
            host                    = "localhost"
            transport               = "HTTP"
            header = [
              {
                name  = "X-Startup-Check"
                value = "true"
              }
            ]
          }
        ]

        volume_mounts = [
          {
            name     = "app-data"
            path     = "/mnt/data"
            sub_path = "nested/path"
          }
        ]
      }
    }

    init_container = {
      app_init = {
        name    = "init-db-setup"
        image   = "busybox:latest"
        cpu     = 0.25
        memory  = "0.5Gi"
        command = ["/bin/sh", "-c"]
        args    = ["echo Initializing DB; sleep 5;"]

        env = [
          {
            name        = "INIT_MODE"
            value       = "setup"
            secret_name = "test-secret"
          }
        ]

        volume_mounts = [
          {
            name     = "init-volume"
            path     = "/mnt/init"
            sub_path = "init/config"
          }
        ]
      }
    }

    volume = [
      {
        name         = "app-data"
        storage_type = "EmptyDir"
      },
      {
        name         = "init-volume"
        storage_type = "EmptyDir"
      }
    ]

    azure_queue_scale_rules = [
      {
        name         = "scale-queue"
        queue_name   = "my-queue-name"
        queue_length = "5"

        authentication = [
          {
            secret_name       = "azure-storage-secret"
            trigger_parameter = "connection"
          }
        ]
      }
    ]

    custom_scale_rules = [
      {
        name             = "my-custom-scaler"
        custom_rule_type = "azure-servicebus"
        metadata = {
          queueName    = "orders"
          namespace    = "myservicebus"
          messageCount = "10"
        }

        authentication = [
          {
            secret_name       = "azure-storage-secret"
            trigger_parameter = "connection"
          }
        ]
      }
    ]

    http_scale_rules = [
      {
        name                = "http-rule"
        concurrent_requests = 100

        authentication = [
          {
            secret_name       = "azure-storage-secret"
            trigger_parameter = "connection"
          }
        ]
      }
    ]
  }

  ingress = {
    allow_insecure_connections = false
    external_enabled           = true
    target_port                = 80
    transport                  = "auto"
    client_certificate_mode    = "accept"

    cors = {
      allowed_origins           = ["https://example.com", "https://another.com"]
      allow_credentials_enabled = true
      allowed_headers           = ["Content-Type", "Authorization", "x-api-key"]
      allowed_methods           = ["GET", "POST", "PUT", "DELETE"]
      exposed_headers           = ["X-Example-Header", "X-Another-Header"]
    }

    ip_security_restriction = [
      {
        name             = "AllowInternal"
        description      = "Allow internal subnet"
        ip_address_range = "10.0.0.0/16"
        action           = "Allow"
      }
    ]

    traffic_weight = [
      {
        label           = "prod-v1"
        latest_revision = true
        revision_suffix = "v1"
        percentage      = 100
      }
    ]
  }

  secret = {
    my_inline_secret = {
      name  = "my-inline-secret"
      value = "super-secret-value"
    },
    test-secret = {
      name  = "test-secret"
      value = "super-secret-init-mode"
    }
  }

  dapr = {
    app_id       = "my-dapr-app"
    app_port     = 80
    app_protocol = "http"
  }
}

##### Container Apps Job Example #####

module "container_job" {
  source = "../../"

  container_type               = "job"
  name                         = "example-job"
  location                     = azurerm_resource_group.ca-rg.location
  resource_group_name          = azurerm_resource_group.ca-rg.name
  container_app_environment_id = module.ca-environment.resource.id
  workload_profile_name        = "Consumption"

  tags = {
    environment = "dev"
    app         = "example"
  }

  revision_mode              = "Single"
  replica_timeout_in_seconds = 3600
  replica_retry_limit        = 5

  template = {
    container = {
      echo-example = {
        name    = "example-container"
        cpu     = 0.5
        memory  = "1.0Gi"
        image   = "alpine:3.18"
        args    = ["-c", "echo Hello from Container Job && sleep 3600"]
        command = ["/app/start"]

        env = [
          {
            name  = "ENV_VAR"
            value = "value"
          }
        ]
      }
    }

    init_container = {
      job_init = {
        name    = "init-input-fetch"
        image   = "alpine:3.18"
        cpu     = 0.25
        memory  = "0.5Gi"
        command = ["/bin/sh", "-c"]
        args    = ["echo Fetching input files...; wget -O /mnt/init/data.json https://example.com/data.json; sleep 3"]

        env = [
          {
            name        = "INIT_MODE"
            value       = "download"
            secret_name = "job-init-secret"
          }
        ]

        volume_mounts = [
          {
            name     = "init-volume-job"
            path     = "/mnt/init"
            sub_path = "input/config"
          }
        ]
      }
    }

    volume = [
      {
        name         = "init-volume-job"
        storage_type = "EmptyDir"
      }
    ]
  }

  secret = {
    mysecret = {
      name  = "job-init-secret"
      value = "sensitive-value"
    }
  }

  schedule_trigger_config = [
    {
      cron_expression          = "0 2 * * *" # Every day at 2 AM
      parallelism              = 3
      replica_completion_count = 1
    }
  ]
}

Requirements

Name Version
terraform ~> 1.9.0
azurerm >=4.0.0

Providers

Name Version
azurerm >=4.0.0

Resources

Name Type
azurerm_container_app.this resource
azurerm_container_app_job.this resource
azurerm_management_lock.lock_app resource
azurerm_management_lock.lock_job resource
azurerm_role_assignment.this resource

Inputs

Name Description Type Default Required
container_app_environment_id * container_app_environment_id - (Required) The ID of the Container App Environment within which this Container App/Job should exist. Changing this forces a new resource to be created.

Example Input:
container_app_environment_id = "/subscriptions/<subscription_id>/resourceGroups/myResourceGroup/providers/Microsoft.App/containerApps/myContainerAppEnvironment"
string n/a yes
name * name - (Required) The name for this Container App/Job. Changing this forces a new resource to be created.

Example Input:
name = "my-container"
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 = "myResourceGroup"
string n/a yes
revision_mode * revision_mode - (Required) The revisions operational mode for the Container App. Possible values include Single and Multiple. In Single mode, a single revision is in operation at any given time. In Multiple mode, more than one revision can be active at a time and can be configured with load distribution via the traffic_weight block in the ingress configuration.

~> Note: This variable is used only for container apps.

Example Input:
revision_mode = "Single"
string n/a yes
template * template - (Required) A template block as detailed below.
* init_container - (Optional) The definition of an init container that is part of the group as documented in the init_container block below.
* args - (Optional) A list of extra arguments to pass to the container.
* command - (Optional) A command to pass to the container to override the default. This is provided as a list of command line elements without spaces.
* cpu - (Optional) The amount of vCPU to allocate to the container. Possible values include 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, and 2.0. When there's a workload profile specified, there's no such constraint.

~> Note: cpu and memory must be specified in 0.25'/'0.5Gi combination increments. e.g. 1.0 / 2.0 or 0.5 / 1.0
* env - (Optional) One or more env blocks as detailed below.
* name - (Required) The name of the environment variable for the container.
* secret_name - (Optional) The name of the secret that contains the value for this environment variable.
* value - (Optional) The value for this environment variable.

~> Note: This value is ignored if secret_name is used
* ephemeral_storage - The amount of ephemeral storage available to the Container App/Job.

~> Note: ephemeral_storage is currently in preview and not configurable at this time.
* image - (Required) The image to use to create the container.
* memory - (Optional) The amount of memory to allocate to the container. Possible values are 0.5Gi, 1Gi, 1.5Gi, 2Gi, 2.5Gi, 3Gi, 3.5Gi and 4Gi. When there's a workload profile specified, there's no such constraint.

~> Note: cpu and memory must be specified in 0.25'/'0.5Gi combination increments. e.g. 1.25 / 2.5Gi or 0.75 / 1.5Gi
* name - (Required) The name of the container
* volume_mounts - (Optional) A volume_mounts block as detailed below.
* name - (Required) The name of the Volume to be mounted in the container.
* path - (Required) The path in the container at which to mount this volume.
* sub_path - (Optional) The sub path of the volume to be mounted in the container.
* container - (Required) One or more container blocks as detailed below.
* args - (Optional) A list of extra arguments to pass to the container.
* command - (Optional) A command to pass to the container to override the default. This is provided as a list of command line elements without spaces.
* cpu - (Required) The amount of vCPU to allocate to the container. Possible values include 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, and 2.0. When there's a workload profile specified, there's no such constraint.

~> Note: cpu and memory must be specified in 0.25'/'0.5Gi combination increments. e.g. 1.0 / 2.0 or 0.5 / 1.0
* env - (Optional) One or more env blocks as detailed below.
* name - (Required) The name of the environment variable for the container.
* secret_name - (Optional) The name of the secret that contains the value for this environment variable.
* value - (Optional) The value for this environment variable.

~> Note: This value is ignored if secret_name is used
* ephemeral_storage - The amount of ephemeral storage available to the Container App/Job.

~> Note: ephemeral_storage is currently in preview and not configurable at this time.
* image - (Required) The image to use to create the container.
* memory - (Required) The amount of memory to allocate to the container. Possible values are 0.5Gi, 1Gi, 1.5Gi, 2Gi, 2.5Gi, 3Gi, 3.5Gi and 4Gi. When there's a workload profile specified, there's no such constraint.
* name - (Required) The name of the container
* liveness_probe - (Optional) A liveness_probe block as detailed below.
* failure_count_threshold - (Optional) The number of consecutive failures required to consider this probe as failed. Possible values are between 1 and 10. Defaults to 3.
* header - (Optional) A header block as detailed below.
* name - (Required) The HTTP Header Name.
* value - (Required) The HTTP Header value.
* host - (Optional) The probe hostname. Defaults to the pod IP address. Setting a value for Host in headers can be used to override this for HTTP and HTTPS type probes.
* initial_delay - (Optional) The number of seconds elapsed after the container has started before the probe is initiated. Possible values are between 0 and 60. Defaults to 1 seconds.
* interval_seconds - (Optional) How often, in seconds, the probe should run. Possible values are in the range 1 - 240. Defaults to 10.
* path - (Optional) The URI to use with the host for http type probes. Not valid for TCP type probes. Defaults to /.
* port - (Required) The port number on which to connect. Possible values are between 1 and 65535.
* timeout - (Optional) Time in seconds after which the probe times out. Possible values are in the range 1 - 240. Defaults to 1.
* transport - (Required) Type of probe. Possible values are TCP, HTTP, and HTTPS.


~> Note: cpu and memory must be specified in 0.25'/'0.5Gi combination increments. e.g. 1.25 / 2.5Gi or 0.75 / 1.5Gi
* readiness_probe - (Optional) A readiness_probe block as detailed below.
* failure_count_threshold - (Optional) The number of consecutive failures required to consider this probe as failed. Possible values are between 1 and 30. Defaults to 3.
* header - (Optional) A header block as detailed below.
* name - (Required) The HTTP Header Name.
* value - (Required) The HTTP Header value.
* host - (Optional) The probe hostname. Defaults to the pod IP address. Setting a value for Host in headers can be used to override this for HTTP and HTTPS type probes.
* initial_delay - (Optional) The number of seconds elapsed after the container has started before the probe is initiated. Possible values are between 0 and 60. Defaults to 0 seconds.
* interval_seconds - (Optional) How often, in seconds, the probe should run. Possible values are between 1 and 240. Defaults to 10
* path - (Optional) The URI to use for http type probes. Not valid for TCP type probes. Defaults to /.
* port - (Required) The port number on which to connect. Possible values are between 1 and 65535.
* success_count_threshold - (Optional) The number of consecutive successful responses required to consider this probe as successful. Possible values are between 1 and 10. Defaults to 3.
* timeout - (Optional) Time in seconds after which the probe times out. Possible values are in the range 1 - 240. Defaults to 1.
* transport - (Required) Type of probe. Possible values are TCP, HTTP, and HTTPS.
* startup_probe - (Optional) A startup_probe block as detailed below.
* failure_count_threshold - (Optional) The number of consecutive failures required to consider this probe as failed. Possible values are between 1 and 30. Defaults to 3.
* header - (Optional) A header block as detailed below.
* name - (Required) The HTTP Header Name.
* value - (Required) The HTTP Header value.
* host - (Optional) The value for the host header which should be sent with this probe. If unspecified, the IP Address of the Pod is used as the host header. Setting a value for Host in headers can be used to override this for HTTP and HTTPS type probes.
* initial_delay - (Optional) The number of seconds elapsed after the container has started before the probe is initiated. Possible values are between 0 and 60. Defaults to 0 seconds.
* interval_seconds - (Optional) How often, in seconds, the probe should run. Possible values are between 1 and 240. Defaults to 10
* path - (Optional) The URI to use with the host for http type probes. Not valid for TCP type probes. Defaults to /.
* port - (Required) The port number on which to connect. Possible values are between 1 and 65535.
* timeout - (Optional) Time in seconds after which the probe times out. Possible values are in the range 1 - 240. Defaults to 1.
* transport - (Required) Type of probe. Possible values are TCP, HTTP, and HTTPS.
* volume_mounts - (Optional) A volume_mounts block as detailed below.
* name - (Required) The name of the Volume to be mounted in the container.
* path - (Required) The path in the container at which to mount this volume.
* sub_path - (Optional) The sub path of the volume to be mounted in the container.
* max_replicas - (Optional) The maximum number of replicas for this container.
* min_replicas - (Optional) The minimum number of replicas for this container.
* azure_queue_scale_rule - (Optional) One or more azure_queue_scale_rule blocks as defined below.
* name - (Required) The name of the Scaling Rule
* queue_name - (Required) The name of the Azure Queue
* queue_length - (Required) The value of the length of the queue to trigger scaling actions.
* authentication - (Required) One or more authentication blocks as defined below.
* secret_name - (Required) The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - (Required) The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* custom_scale_rule - (Optional) One or more custom_scale_rule blocks as defined below.
* name - (Required) The name of the Scaling Rule
* custom_rule_type - (Required) The Custom rule type. Possible values include: activemq, artemis-queue, kafka, pulsar, aws-cloudwatch, aws-dynamodb, aws-dynamodb-streams, aws-kinesis-stream, aws-sqs-queue, azure-app-insights, azure-blob, azure-data-explorer, azure-eventhub, azure-log-analytics, azure-monitor, azure-pipelines, azure-servicebus, azure-queue, cassandra, cpu, cron, datadog, elasticsearch, external, external-push, gcp-stackdriver, gcp-storage, gcp-pubsub, graphite, http, huawei-cloudeye, ibmmq, influxdb, kubernetes-workload, liiklus, memory, metrics-api, mongodb, mssql, mysql, nats-jetstream, stan, tcp, new-relic, openstack-metric, openstack-swift, postgresql, predictkube, prometheus, rabbitmq, redis, redis-cluster, redis-sentinel, redis-streams, redis-cluster-streams, redis-sentinel-streams, selenium-grid,solace-event-queue, and github-runner.
* metadata - (Required) - A map of string key-value pairs to configure the Custom Scale Rule.
* authentication - (Optional) Zero or more authentication blocks as defined below.
* secret_name - (Required) The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - (Required) The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* http_scale_rule - (Optional) One or more http_scale_rule blocks as defined below.
* name - (Required) The name of the Scaling Rule
* concurrent_requests - (Required) - The number of concurrent requests to trigger scaling.
* authentication - (Optional) Zero or more authentication blocks as defined below.
* secret_name - (Required) The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - (Required) The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* tcp_scale_rule - (Optional) One or more tcp_scale_rule blocks as defined below.
* name - (Required) The name of the Scaling Rule
* concurrent_requests - (Required) - The number of concurrent requests to trigger scaling.
* authentication - (Optional) Zero or more authentication blocks as defined below.
* secret_name - (Required) The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - (Required) The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* revision_suffix - (Optional) The suffix for the revision. This value must be unique for the lifetime of the Resource. If omitted the service will use a hash function to create one.
* termination_grace_period_seconds - (Optional) The time in seconds after the container is sent the termination signal before the process if forcibly killed.
* volume - (Optional) A volume block as detailed below.
* name - (Required) The name of the volume.
* storage_name - (Optional) The name of the AzureFile storage.
* storage_type - (Optional) The type of storage volume. Possible values are AzureFile, EmptyDir and Secret. Defaults to EmptyDir.

Example Input:
template = {
init_container = [
{
name = "init-container-1"
image = "nginx:1.21"
cpu = 0.25
memory = "0.5Gi"
args = ["--debug"]
command = ["/bin/sh", "-c"]
env = [
{
name = "ENV_VAR_1"
value = "value1"
},
{
name = "SECRET_ENV_VAR"
secret_name = "my-secret"
}
]
volume_mounts = [
{
name = "init-volume"
path = "/init-data"
}
]
}
]
container = [
{
name = "app-container"
image = "myapp:latest"
cpu = 1.0
memory = "2Gi"
args = ["--start"]
command = ["/app/entrypoint.sh"]
env = [
{
name = "APP_ENV"
value = "production"
}
]
liveness_probe = [
{
port = 8080
path = "/healthz"
interval_seconds = 10
timeout = 5
transport = "HTTP"
}
]
readiness_probe = [
{
port = 8080
path = "/ready"
interval_seconds = 10
success_count_threshold = 1
transport = "HTTP"
}
]
startup_probe = [
{
port = 8080
path = "/start"
interval_seconds = 5
timeout = 3
transport = "HTTP"
}
]
volume_mounts = [
{
name = "app-volume"
path = "/data"
}
]
}
]
max_replicas = 5
min_replicas = 1
revision_suffix = "v1"
termination_grace_period_seconds = 30
azure_queue_scale_rules = [
{
name = "queue-scale-rule"
queue_length = 100
queue_name = "my-queue"
authentication = [
{
secret_name = "queue-auth-secret"
trigger_parameter = "queueConnectionString"
}
]
}
]
custom_scale_rules = [
{
name = "custom-rule"
custom_rule_type = "cpu"
metadata = {
threshold = "75"
period = "1m"
}
authentication = [
{
secret_name = "custom-auth-secret"
trigger_parameter = "customConnectionString"
}
]
}
]
http_scale_rules = [
{
name = "http-scale-rule"
concurrent_requests = "100"
authentication = [
{
secret_name = "http-auth-secret"
}
]
}
]
volume = [
{
name = "app-volume"
storage_name = "my-storage"
storage_type = "AzureFile"
}
]
}
object({
init_container = optional(map(object({
args = optional(list(string))
command = optional(list(string))
cpu = optional(number)
ephemeral_storage = optional(string)
image = string
memory = optional(string)
name = string
env = optional(list(object({
name = string
secret_name = optional(string)
value = optional(string)
})))
volume_mounts = optional(list(object({
name = string
path = string
sub_path = optional(string)
})))
})))
container = map(object({
args = optional(list(string))
command = optional(list(string))
cpu = number
ephemeral_storage = optional(string)
image = string
memory = string
name = string
env = optional(list(object({
name = string
secret_name = optional(string)
value = optional(string)
})))
liveness_probe = optional(list(object({
failure_count_threshold = optional(number, 3)
header = optional(list(object({
name = string
value = string
})))
host = optional(string)
initial_delay = optional(number, 1)
interval_seconds = optional(number, 10)
path = optional(string, "/")
port = number
timeout = optional(number, 1)
transport = string
})))
readiness_probe = optional(list(object({
failure_count_threshold = optional(number, 3)
header = optional(list(object({
name = string
value = string
})))
host = optional(string)
initial_delay = optional(number, 0)
interval_seconds = optional(number, 10)
path = optional(string, "/")
port = number
success_count_threshold = optional(number, 3)
timeout = optional(number, 1)
transport = string
})))
startup_probe = optional(list(object({
failure_count_threshold = optional(number, 3)
header = optional(list(object({
name = string
value = string
})))
host = optional(string)
initial_delay = optional(number, 0)
interval_seconds = optional(number, 10)
path = optional(string, "/")
port = number
timeout = optional(number, 1)
transport = string
})))
volume_mounts = optional(list(object({
name = string
path = string
sub_path = optional(string)
})))
}))
max_replicas = optional(number)
min_replicas = optional(number)
azure_queue_scale_rules = optional(list(object({
name = string
queue_name = string
queue_length = number
authentication = list(object({
secret_name = string
trigger_parameter = string
}))
})))
custom_scale_rules = optional(list(object({
name = string
custom_rule_type = string
metadata = map(string)
authentication = optional(list(object({
secret_name = string
trigger_parameter = string
})))
})))
http_scale_rules = optional(list(object({
name = string
concurrent_requests = string
authentication = optional(list(object({
secret_name = string
trigger_parameter = optional(string)
})))
})))
tcp_scale_rules = optional(list(object({
name = string
concurrent_requests = string
authentication = optional(list(object({
secret_name = string
trigger_parameter = optional(string)
})))
})))
revision_suffix = optional(string)
termination_grace_period_seconds = optional(number)
volume = optional(list(object({
name = string
storage_name = optional(string)
storage_type = optional(string, "EmptyDir")
mount_options = optional(string)
})))
})
n/a yes
container_type * container_type - (Required) Container Type must be either app or job, default value is app.

Example Input:
container_type = "app"
string "app" no
dapr * dapr - (Optional) A dapr block as detailed below.
* app_id - (Required) The Dapr Application Identifier.
* app_port - (Optional) The port which the application is listening on. This is the same as the ingress port.
* app_protocol - (Optional) The protocol for the app. Possible values include http and grpc. Defaults to http.

Example Input:
dapr = {
app_id = "my-dapr-app"
app_port = 5000
app_protocol = "http"
}
object({
app_id = string
app_port = optional(number)
app_protocol = optional(string, "http")
})
null no
event_trigger_config * event_trigger_config - (Optional) A event_trigger_config block as defined below.
* parallelism - (Optional) Number of parallel replicas of a job that can run at a given time.
* replica_completion_count - (Optional) Minimum number of successful replica completions before overall job completion.
* scale - (Optional) A scale block as defined below.
* max_executions - (Optional) Maximum number of job executions that are created for a trigger.
* min_executions - (Optional) Minimum number of job executions that are created for a trigger.
* polling_interval_in_seconds - (Optional) Interval to check each event source in seconds.
* rules - (Optional) A rules block as defined below.
* name - (Optional) Name of the scale rule.
* custom_rule_type - (Optional) Type of the scale rule.
* metadata - (Optional) Metadata properties to describe the scale rule.
* authentication - (Optional) A authentication block as defined below.
* secret_name - (Optional) Name of the secret from which to pull the auth params.
* trigger_parameter - (Optional) Trigger Parameter that uses the secret.

~> Note: This variable is used only for container job.

Example Input:
event_trigger_config = [
{
parallelism = 2
replica_completion_count = 1
scale = {
my_scale_rule = {
max_executions = 5
min_executions = 1
polling_interval_in_seconds = 30
rules = {
my_rule = {
name = "queue-scale-rule"
custom_rule_type = "azure-queue"
metadata = {
queueName = "my-queue"
queueLength = "5"
}
authentication = {
auth1 = {
secret_name = "azure-storage-secret"
trigger_parameter = "connection"
}
}
}
}
}
}
}
]
list(object({
parallelism = optional(number)
replica_completion_count = optional(number)
scale = map(object({
max_executions = optional(number)
min_executions = optional(number)
polling_interval_in_seconds = optional(number)
rules = map(object({
name = optional(string)
custom_rule_type = optional(string)
metadata = map(string)
authentication = map(object({
secret_name = optional(string)
trigger_parameter = optional(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 = {
system_assigned = true
user_assigned_resource_ids = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/my-identity"
}
object({
type = string
identity_ids = optional(list(string))
})
null no
ingress * ingress - (Optional) An ingress block as detailed below.
* allow_insecure_connections - (Optional) Should this ingress allow insecure connections?
* cors - (Optional) A cors block as defined below.
* allowed_origins - (Required) Specifies the list of origins that are allowed to make cross-origin calls.
* allow_credentials_enabled - (Optional) Whether user credentials are allowed in the cross-origin request is enabled. Defaults to false.
* allowed_headers - (Optional) Specifies the list of request headers that are permitted in the actual request.
* allowed_methods - (Optional) Specifies the list of HTTP methods are allowed when accessing the resource in a cross-origin request.
* exposed_headers - (Optional) Specifies the list of headers exposed to the browser in the response to a cross-origin request.
* max_age_in_seconds - (Optional) Specifies the number of seconds that the browser can cache the results of a preflight request.
* fqdn - The FQDN of the ingress.
* external_enabled - (Optional) Are connections to this Ingress from outside the Container App Environment enabled? Defaults to false.
* ip_security_restriction - (Optional) One or more ip_security_restriction blocks for IP-filtering rules as defined below.
* action - (Required) The IP-filter action. Allow or Deny.

~> Note: The action types in an all ip_security_restriction blocks must be the same for the ingress, mixing Allow and Deny rules is not currently supported by the service.
* description - (Optional) Describe the IP restriction rule that is being sent to the container-app.
* ip_address_range - (Required) The incoming IP address or range of IP addresses (in CIDR notation).
* name - (Required) Name for the IP restriction rule.
* target_port - (Required) The target port on the container for the Ingress traffic.
* exposed_port - (Optional) The exposed port on the container for the Ingress traffic.

~> Note: exposed_port can only be specified when transport is set to tcp.
* traffic_weight - (Required) One or more traffic_weight blocks as detailed below.

~> Note: This block only applies when revision_mode is set to Multiple.
* label - (Optional) The label to apply to the revision as a name prefix for routing traffic.
* latest_revision - (Optional) This traffic Weight applies to the latest stable Container Revision. At most only one traffic_weight block can have the latest_revision set to true.
* revision_suffix - (Optional) The suffix string to which this traffic_weight applies.

~> Note: If latest_revision is false, the revision_suffix shall be specified.
* percentage - (Required) The percentage of traffic which should be sent this revision.

~> Note: The cumulative values for weight must equal 100 exactly and explicitly, no default weights are assumed.
* transport - (Optional) The transport method for the Ingress. Possible values are auto, http, http2 and tcp. Defaults to auto.

~> Note: if transport is set to tcp, exposed_port and target_port should be set at the same time.
* client_certificate_mode - (Optional) The client certificate mode for the Ingress. Possible values are require, accept, and ignore.

Example Input:
ingress = {
ingress1 = {
allow_insecure_connections = false
fqdn = "app.example.com"
cors = {
allowed_origins = ["https://example.com", "https://app.example.com"]
allow_credentials_enabled = true
allowed_headers = ["Content-Type", "Authorization"]
allowed_methods = ["GET", "POST", "OPTIONS"]
exposed_headers = ["X-Custom-Header"]
max_age_in_seconds = 3600
}
external_enabled = true
target_port = 8080
exposed_port = 80
transport = "http"
client_certificate_mode = "accept"
custom_domain = {
certificate_binding_type = "SNI"
certificate_id = "cert-12345"
name = "custom.example.com"
}
ip_security_restriction = [
{
action = "Allow"
description = "Allow traffic from internal network"
ip_address_range = "10.0.0.0/24"
name = "internal-allow"
},
{
action = "Deny"
description = "Block traffic from specific IP range"
ip_address_range = "192.168.1.0/24"
name = "restricted-block"
}
]
traffic_weight = [
{
label = "v1"
latest_revision = false
revision_suffix = "rev1"
percentage = 50
},
{
label = "v2"
latest_revision = true
percentage = 50
}
]
}
}
object({
allow_insecure_connections = optional(bool)
external_enabled = optional(bool, false)
fqdn = optional(string)
cors = optional(object({
allowed_origins = optional(list(string))
allow_credentials_enabled = optional(bool, false)
allowed_headers = optional(list(string))
allowed_methods = optional(list(string))
exposed_headers = optional(list(string))
max_age_in_seconds = optional(number)
}))
ip_security_restriction = optional(list(object({
action = string
description = optional(string)
ip_address_range = string
name = string
})))
target_port = number
exposed_port = optional(number)
traffic_weight = list(object({
label = optional(string)
latest_revision = optional(bool)
revision_suffix = optional(string)
percentage = number
}))
transport = optional(string, "auto")
client_certificate_mode = optional(string)
custom_domain = optional(object({
certificate_binding_type = optional(string)
certificate_id = string
name = string
}))
})
null no
location * location - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created.

~> Note: For Container Apps, the location is the same as the Environment in which it is deployed.

Example Input:
name = "germanywestcetnral"
string null no
lock * lock block as detailed 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 = {
kind = "CanNotDelete"
name = "my-resource-lock"
}
object({
kind = string
name = optional(string)
})
null no
manual_trigger_config * manual_trigger_config - (Optional) A manual_trigger_config block as defined below.
* parallelism - (Optional) Number of parallel replicas of a job that can run at a given time.
* replica_completion_count - (Optional) Minimum number of successful replica completions before overall job completion.

~> Note: This variable is used only for container job.

Example Input:
manual_trigger_config = {
parallelism = 5
replica_completion_count = 3
}
object({
parallelism = optional(number)
replica_completion_count = optional(number)
})
null no
registry * registries - (Optional) A template block as detailed below.
* server - (Required) The hostname for the Container Registry.
The authentication details must also be supplied, identity and username/password_secret_name are mutually exclusive.
* identity - (Optional) Resource ID for the User Assigned Managed identity to use when pulling from the Container Registry.

~> Note: The Resource ID must be of a User Assigned Managed identity defined in an identity block.
* password_secret_name - (Optional) The name of the Secret Reference containing the password value for this user on the Container Registry, username must also be supplied.
* username - (Optional) The username to use for this Container Registry, password_secret_name must also be supplied..

Example Input:
registries = {
registry1 = {
server = "mycontainerregistry.azurecr.io"
username = "myregistryuser"
password_secret_name = "myregistrysecret"
},
registry2 = {
server = "anotherregistry.azurecr.io"
identity = "/subscriptions/xxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity"
}
}
map(object({
server = string
identity = optional(string)
password_secret_name = optional(string)
username = optional(string)
}))
null no
replica_retry_limit * replica_retry_limit - (Optional) The maximum number of times a replica is allowed to retry.

~> Note: This variable is used only for container job.

Example Input:
replica_retry_limit = 5
number null no
replica_timeout_in_seconds * replica_timeout_in_seconds - (Required) The maximum number of seconds a replica is allowed to run.

~> Note: This variable is used only for container job.

Example Input:
replica_timeout_in_seconds = 3600
number null no
role_assignment * role_assignment block as detailed 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 = {
"assignment1" = {
role_definition_id_or_name = "Contributor"
principal_id = "11111111-2222-3333-4444-555555555555"
description = "Granting contributor access"
skip_service_principal_aad_check = false
principal_type = "User"
},
"assignment2" = {
role_definition_id_or_name = "Reader"
principal_id = "66666666-7777-8888-9999-000000000000"
skip_service_principal_aad_check = true
principal_type = "ServicePrincipal"
}
}
map(object({
role_definition_id_or_name = string
principal_id = string
description = optional(string)
skip_service_principal_aad_check = optional(bool, false)
condition = optional(string)
condition_version = optional(string)
delegated_managed_identity_resource_id = optional(string)
principal_type = optional(string)
}))
null no
schedule_trigger_config * schedule_trigger_config - (Optional) A schedule_trigger_config block as defined below.

~> Note: Only one of manual_trigger_config, event_trigger_config or schedule_trigger_config can be specified.
* cron_expression - (Required) Cron formatted repeating schedule of a Cron Job.
* parallelism - (Optional) Number of parallel replicas of a job that can run at a given time.
* replica_completion_count - (Optional) Minimum number of successful replica completions before overall job completion.

~> Note: This variable is used only for container job.

Example Input:
schedule_trigger_config = [
{
cron_expression = "0 0 * * *"
parallelism = 5
replica_completion_count = 3
}
]
list(object({
cron_expression = string
parallelism = optional(number)
replica_completion_count = optional(number)
}))
null no
secret * secrets - (Optional) A secrets block as detailed below.
* name - (Required) The secret name.
* identity - (Optional) The identity to use for accessing the Key Vault secret reference. This can either be the Resource ID of a User Assigned Identity, or System for the System Assigned Identity.

~> Note: identity must be used together with key_vault_secret_id
* key_vault_secret_id - (Optional) The ID of a Key Vault secret. This can be a versioned or version-less ID.

~> Note: When using key_vault_secret_id, ignore_changes should be used to ignore any changes to value.
* value - (Optional) The value for this secret.

~> Note: value will be ignored if key_vault_secret_id and identity are provided.

Example Input:
secrets = {
"db_password" = {
identity = "/subscriptions/xxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myIdentity"
key_vault_secret_id = "/subscriptions/xxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myKeyVault/secrets/dbPassword"
name = "db_password"
},
"api_key" = {
name = "api_key"
value = "s3cr3tAPIkey123"
},
"system_secret" = {
identity = "System"
name = "system_secret_name"
}
}
map(object({
name = string
identity = optional(string)
key_vault_secret_id = optional(string)
value = optional(string)
}))
null no
tags * tags - (Optional) A map of tags to associate with the network and subnets.

Example Input:
tags = {
"environment" = "production"
"department" = "IT"
}
map(string) null no
timeouts * timeouts block as detailed below.
* create - (Defaults to 30 minutes) Used when creating the Container App/Job.
* delete - (Defaults to 30 minutes) Used when deleting the Container App/Job.
* read - (Defaults to 5 minutes) Used when retrieving the Container App/Job.
* update - (Defaults to 30 minutes) Used when updating the Container App/Job.

Example Input:
container_app_timeouts = {
create = "45m"
delete = "30m"
read = "10m"
update = "40m"
}
object({
create = optional(string, "30")
delete = optional(string, "5")
read = optional(string, "30")
update = optional(string, "30")
})
null no
workload_profile_name * workload_profile_name - (Optional) The name of the Workload Profile in the Container App Environment to place this Container App/Job.

Example Input:
workload_profile_name = "standard-workload-profile"
string null no

Outputs

Name Description
container_app * container_app_environment_id - The ID of the Container App Environment this Container App is linked to.
* name - The name of the Container App.
* resource_group_name - The name of the Resource Group where this Container App exists.
* revision_mode - The revision mode of the Container App.
* workload_profile_name - The name of the Workload Profile in the Container App Environment in which this Container App is running.
* tags - A mapping of tags to assign to the Container App.

A template block exports the following:
* init_container - One or more init_container blocks detailed below.
* args - A list of extra arguments to pass to the container.
* command - A command to pass to the container to override the default. This is provided as a list of command line elements without spaces.
* cpu - The amount of vCPU to allocate to the container. Possible values include 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, and 2.0.
* env - One or more env blocks as detailed below.
* name - The name of the environment variable for the container.
* secret_name - The name of the secret that contains the value for this environment variable.
* value - The value for this environment variable.
* ephemeral_storage - The amount of ephemeral storage available to the Container App.
* image - The image to use to create the container.
* memory - The amount of memory to allocate to the container. Possible values are 0.5Gi, 1Gi, 1.5Gi, 2Gi, 2.5Gi, 3Gi, 3.5Gi and 4Gi.
* name - The name of the container
* volume_mounts - A volume_mounts block as detailed below.
* name - The name of the Volume to be mounted in the container.
* path - The path in the container at which to mount this volume.
* sub_path - The sub path of the volume to be mounted in the container.
* container - One or more container blocks as detailed below.
* args - A list of extra arguments to pass to the container.
* command - A command to pass to the container to override the default. This is provided as a list of command line elements without spaces.
* cpu - The amount of vCPU to allocate to the container. Possible values include 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, and 2.0.
* env - One or more env blocks as detailed below.
* name - The name of the environment variable for the container.
* secret_name - The name of the secret that contains the value for this environment variable.
* value - The value for this environment variable.
* ephemeral_storage - The amount of ephemeral storage available to the Container App.
* image - The image to use to create the container.
* memory - The amount of memory to allocate to the container. Possible values are 0.5Gi, 1Gi, 1.5Gi, 2Gi, 2.5Gi, 3Gi, 3.5Gi and 4Gi.
* name - The name of the container
* liveness_probe - A liveness_probe block as detailed below.
* failure_count_threshold - The number of consecutive failures required to consider this probe as failed. Possible values are between 1 and 10. Defaults to 3.
* header - A header block as detailed below.
* name - The HTTP Header Name.
* value - The HTTP Header value.
* host - The probe hostname. Defaults to the pod IP address. Setting a value for Host in headers can be used to override this for HTTP and HTTPS type probes.
* initial_delay - The number of seconds elapsed after the container has started before the probe is initiated. Possible values are between 0 and 60. Defaults to 1 seconds.
* interval_seconds - How often, in seconds, the probe should run. Possible values are in the range 1 - 240. Defaults to 10.
* path - The URI to use with the host for http type probes. Not valid for TCP type probes. Defaults to /.
* port - The port number on which to connect. Possible values are between 1 and 65535.
* timeout - Time in seconds after which the probe times out. Possible values are in the range 1 - 240. Defaults to 1.
* transport - Type of probe. Possible values are TCP, HTTP, and HTTPS.
* readiness_probe - A readiness_probe block as detailed below.
* failure_count_threshold - The number of consecutive failures required to consider this probe as failed. Possible values are between 1 and 30. Defaults to 3.
* header - A header block as detailed below.
* name - The HTTP Header Name.
* value - The HTTP Header value.
* host - The probe hostname. Defaults to the pod IP address. Setting a value for Host in headers can be used to override this for HTTP and HTTPS type probes.
* initial_delay - The number of seconds elapsed after the container has started before the probe is initiated. Possible values are between 0 and 60. Defaults to 0 seconds.
* interval_seconds - How often, in seconds, the probe should run. Possible values are between 1 and 240. Defaults to 10
* path - The URI to use for http type probes. Not valid for TCP type probes. Defaults to /.
* port - The port number on which to connect. Possible values are between 1 and 65535.
* success_count_threshold - The number of consecutive successful responses required to consider this probe as successful. Possible values are between 1 and 10. Defaults to 3.
* timeout - Time in seconds after which the probe times out. Possible values are in the range 1 - 240. Defaults to 1.
* transport - Type of probe. Possible values are TCP, HTTP, and HTTPS.
* startup_probe - A startup_probe block as detailed below.
* failure_count_threshold - The number of consecutive failures required to consider this probe as failed. Possible values are between 1 and 30. Defaults to 3.
* header - A header block as detailed below.
* name - The HTTP Header Name.
* value - The HTTP Header value.
* host - The value for the host header which should be sent with this probe. If unspecified, the IP Address of the Pod is used as the host header. Setting a value for Host in headers can be used to override this for HTTP and HTTPS type probes.
* initial_delay - The number of seconds elapsed after the container has started before the probe is initiated. Possible values are between 0 and 60. Defaults to 0 seconds.
* interval_seconds - How often, in seconds, the probe should run. Possible values are between 1 and 240. Defaults to 10
* path - The URI to use with the host for http type probes. Not valid for TCP type probes. Defaults to /.
* port - The port number on which to connect. Possible values are between 1 and 65535.
* timeout - Time in seconds after which the probe times out. Possible values are in the range 1 - 240. Defaults to 1.
* transport - Type of probe. Possible values are TCP, HTTP, and HTTPS.
* volume_mounts - A volume_mounts block as detailed below.
* name - The name of the Volume to be mounted in the container.
* path - The path in the container at which to mount this volume.
* sub_path - The sub path of the volume to be mounted in the container.
* max_replicas - The maximum number of replicas for this container.
* min_replicas - The minimum number of replicas for this container.
* azure_queue_scale_rule - One or more azure_queue_scale_rule blocks as defined below.
* name - The name of the Scaling Rule
* queue_name - The name of the Azure Queue
* queue_length - The value of the length of the queue to trigger scaling actions.
* authentication - One or more authentication blocks as defined below.
* secret_name - The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* custom_scale_rule - One or more custom_scale_rule blocks as defined below.
* name - The name of the Scaling Rule
* custom_rule_type - The Custom rule type. Possible values include: activemq, artemis-queue, kafka, pulsar, aws-cloudwatch, aws-dynamodb, aws-dynamodb-streams, aws-kinesis-stream, aws-sqs-queue, azure-app-insights, azure-blob, azure-data-explorer, azure-eventhub, azure-log-analytics, azure-monitor, azure-pipelines, azure-servicebus, azure-queue, cassandra, cpu, cron, datadog, elasticsearch, external, external-push, gcp-stackdriver, gcp-storage, gcp-pubsub, graphite, http, huawei-cloudeye, ibmmq, influxdb, kubernetes-workload, liiklus, memory, metrics-api, mongodb, mssql, mysql, nats-jetstream, stan, tcp, new-relic, openstack-metric, openstack-swift, postgresql, predictkube, prometheus, rabbitmq, redis, redis-cluster, redis-sentinel, redis-streams, redis-cluster-streams, redis-sentinel-streams, selenium-grid,solace-event-queue, and github-runner.
* metadata - A map of string key-value pairs to configure the Custom Scale Rule.
* authentication - Zero or more authentication blocks as defined below.
* secret_name - The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* http_scale_rule - One or more http_scale_rule blocks as defined below.
* name - The name of the Scaling Rule
* concurrent_requests - The number of concurrent requests to trigger scaling.
* authentication - Zero or more authentication blocks as defined below.
* secret_name - The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* tcp_scale_rule - One or more tcp_scale_rule blocks as defined below.
* name - The name of the Scaling Rule
* concurrent_requests - The number of concurrent requests to trigger scaling.
* authentication - Zero or more authentication blocks as defined below.
* secret_name - The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* revision_suffix - The suffix for the revision. This value must be unique for the lifetime of the Resource. If omitted the service will use a hash function to create one.
* termination_grace_period_seconds - The time in seconds after the container is sent the termination signal before the process if forcibly killed.
* volume - A volume block as detailed below.
* name - The name of the volume.
* storage_name - The name of the AzureFile storage.
* storage_type - The type of storage volume. Possible values are AzureFile, EmptyDir and Secret. Defaults to EmptyDir.

An identity block supports the following:
* type - The type of managed identity to assign. Possible values are UserAssigned and SystemAssigned
* identity_ids - A list of one or more Resource IDs for User Assigned Managed identities to assign. Required when type is set to UserAssigned.

A secrets block supports the following:
* name - The secret name.
* identity - The identity to use for accessing the Key Vault secret reference. This can either be the Resource ID of a User Assigned Identity, or System for the System Assigned Identity.
* key_vault_secret_id - The ID of a Key Vault secret. This can be a versioned or version-less ID.
* value - The value for this secret.

An ingress block supports the following:
* allow_insecure_connections - Should this ingress allow insecure connections?
* cors - A cors block as defined below.
* allowed_origins - Specifies the list of origins that are allowed to make cross-origin calls.
* allow_credentials_enabled - Whether user credentials are allowed in the cross-origin request is enabled. Defaults to false.
* allowed_headers - Specifies the list of request headers that are permitted in the actual request.
* allowed_methods - Specifies the list of HTTP methods are allowed when accessing the resource in a cross-origin request.
* exposed_headers - Specifies the list of headers exposed to the browser in the response to a cross-origin request.
* max_age_in_seconds - Specifies the number of seconds that the browser can cache the results of a preflight request.
* fqdn - The FQDN of the ingress.
* external_enabled - Are connections to this Ingress from outside the Container App Environment enabled? Defaults to false.
* ip_security_restriction - One or more ip_security_restriction blocks for IP-filtering rules as defined below.
* action - The IP-filter action. Allow or Deny.
* description - Describe the IP restriction rule that is being sent to the container-app.
* ip_address_range - The incoming IP address or range of IP addresses (in CIDR notation).
* name - Name for the IP restriction rule.
* target_port - The target port on the container for the Ingress traffic.
* exposed_port - The exposed port on the container for the Ingress traffic.
* traffic_weight - One or more traffic_weight blocks as detailed below.
* label - The label to apply to the revision as a name prefix for routing traffic.
* latest_revision - This traffic Weight applies to the latest stable Container Revision. At most only one traffic_weight block can have the latest_revision set to true.
* revision_suffix - The suffix string to which this traffic_weight applies.
* percentage - The percentage of traffic which should be sent this revision.
* transport - The transport method for the Ingress. Possible values are auto, http, http2 and tcp. Defaults to auto.
* client_certificate_mode - The client certificate mode for the Ingress. Possible values are require, accept, and ignore.

A dapr block supports the following:
* app_id - The Dapr Application Identifier.
* app_port - The port which the application is listening on. This is the same as the ingress port.
* app_protocol - The protocol for the app. Possible values include http and grpc. Defaults to http.

A registry block supports the following:
* server - The hostname for the Container Registry.
* username - The username to use for this Container Registry, password_secret_name must also be supplied..
* password_secret_name - The name of the Secret Reference containing the password value for this user on the Container Registry, username must also be supplied.
* identity - Resource ID for the User Assigned Managed identity to use when pulling from the Container Registry.

Example output:
output "name" {
value = module.module_name.container_app.name
}
container_job * name - Specifies the name of the Container App Job. Changing this forces a new resource to be created.
* resource_group_name - The name of the resource group in which to create the resource. Changing this forces a new resource to be created.
* location - Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created.
* environment_id - The ID of the Container Apps Environment in which to create the Container App Job. Changing this forces a new resource to be created.
* replica_timeout_in_seconds - The maximum number of seconds a replica is allowed to run.
* workload_profile_name - The name of the workload profile to use for the Container App Job.
* replica_retry_limit - The maximum number of times a replica is allowed to retry.
* tags - A mapping of tags to assign to the resource.

A template block supports the following:
* init_container - The definition of an init container that is part of the group as documented in the init_container block below.
* args - A list of extra arguments to pass to the container.
* command - A command to pass to the container to override the default. This is provided as a list of command line elements without spaces.
* cpu - The amount of vCPU to allocate to the container. Possible values include 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, and 2.0. When there's a workload profile specified, there's no such constraint.
* env - One or more env blocks as detailed below.
* name - The name of the environment variable for the container.
* secret_name - The name of the secret that contains the value for this environment variable.
* value - The value for this environment variable.
* ephemeral_storage - The amount of ephemeral storage available to the Container App/Job.
* image - The image to use to create the container.
* memory - The amount of memory to allocate to the container. Possible values are 0.5Gi, 1Gi, 1.5Gi, 2Gi, 2.5Gi, 3Gi, 3.5Gi and 4Gi. When there's a workload profile specified, there's no such constraint.
* name - The name of the container
* volume_mounts - A volume_mounts block as detailed below.
* name - The name of the Volume to be mounted in the container.
* path - The path in the container at which to mount this volume.
* sub_path - The sub path of the volume to be mounted in the container.
* container - One or more container blocks as detailed below.
* args - A list of extra arguments to pass to the container.
* command - A command to pass to the container to override the default. This is provided as a list of command line elements without spaces.
* cpu - The amount of vCPU to allocate to the container. Possible values include 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, and 2.0. When there's a workload profile specified, there's no such constraint.
* env - One or more env blocks as detailed below.
* name - The name of the environment variable for the container.
* secret_name - The name of the secret that contains the value for this environment variable.
* value - The value for this environment variable.
* ephemeral_storage - The amount of ephemeral storage available to the Container App/Job.
* image - The image to use to create the container.
* memory - The amount of memory to allocate to the container. Possible values are 0.5Gi, 1Gi, 1.5Gi, 2Gi, 2.5Gi, 3Gi, 3.5Gi and 4Gi. When there's a workload profile specified, there's no such constraint.
* name - The name of the container
* liveness_probe - A liveness_probe block as detailed below.
* failure_count_threshold - The number of consecutive failures required to consider this probe as failed. Possible values are between 1 and 10. Defaults to 3.
* header - A header block as detailed below.
* name - The HTTP Header Name.
* value - The HTTP Header value.
* host - The probe hostname. Defaults to the pod IP address. Setting a value for Host in headers can be used to override this for HTTP and HTTPS type probes.
* initial_delay - The number of seconds elapsed after the container has started before the probe is initiated. Possible values are between 0 and 60. Defaults to 1 seconds.
* interval_seconds - How often, in seconds, the probe should run. Possible values are in the range 1 - 240. Defaults to 10.
* path - The URI to use with the host for http type probes. Not valid for TCP type probes. Defaults to /.
* port - The port number on which to connect. Possible values are between 1 and 65535.
* timeout - Time in seconds after which the probe times out. Possible values are in the range 1 - 240. Defaults to 1.
* transport - Type of probe. Possible values are TCP, HTTP, and HTTPS.
* readiness_probe - A readiness_probe block as detailed below.
* failure_count_threshold - The number of consecutive failures required to consider this probe as failed. Possible values are between 1 and 30. Defaults to 3.
* header - A header block as detailed below.
* name - The HTTP Header Name.
* value - The HTTP Header value.
* host - The probe hostname. Defaults to the pod IP address. Setting a value for Host in headers can be used to override this for HTTP and HTTPS type probes.
* initial_delay - The number of seconds elapsed after the container has started before the probe is initiated. Possible values are between 0 and 60. Defaults to 0 seconds.
* interval_seconds - How often, in seconds, the probe should run. Possible values are between 1 and 240. Defaults to 10
* path - The URI to use for http type probes. Not valid for TCP type probes. Defaults to /.
* port - The port number on which to connect. Possible values are between 1 and 65535.
* success_count_threshold - The number of consecutive successful responses required to consider this probe as successful. Possible values are between 1 and 10. Defaults to 3.
* timeout - Time in seconds after which the probe times out. Possible values are in the range 1 - 240. Defaults to 1.
* transport - Type of probe. Possible values are TCP, HTTP, and HTTPS.
* startup_probe - A startup_probe block as detailed below.
* failure_count_threshold - The number of consecutive failures required to consider this probe as failed. Possible values are between 1 and 30. Defaults to 3.
* header - A header block as detailed below.
* name - The HTTP Header Name.
* value - The HTTP Header value.
* host - The value for the host header which should be sent with this probe. If unspecified, the IP Address of the Pod is used as the host header. Setting a value for Host in headers can be used to override this for HTTP and HTTPS type probes.
* initial_delay - The number of seconds elapsed after the container has started before the probe is initiated. Possible values are between 0 and 60. Defaults to 0 seconds.
* interval_seconds - How often, in seconds, the probe should run. Possible values are between 1 and 240. Defaults to 10
* path - The URI to use with the host for http type probes. Not valid for TCP type probes. Defaults to /.
* port - The port number on which to connect. Possible values are between 1 and 65535.
* timeout - Time in seconds after which the probe times out. Possible values are in the range 1 - 240. Defaults to 1.
* transport - Type of probe. Possible values are TCP, HTTP, and HTTPS.
* volume_mounts - A volume_mounts block as detailed below.
* name - The name of the Volume to be mounted in the container.
* path - The path in the container at which to mount this volume.
* sub_path - The sub path of the volume to be mounted in the container.
* max_replicas - The maximum number of replicas for this container.
* min_replicas - The minimum number of replicas for this container.
* azure_queue_scale_rule - One or more azure_queue_scale_rule blocks as defined below.
* name - The name of the Scaling Rule
* queue_name - The name of the Azure Queue
* queue_length - The value of the length of the queue to trigger scaling actions.
* authentication - One or more authentication blocks as defined below.
* secret_name - The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* custom_scale_rule - One or more custom_scale_rule blocks as defined below.
* name - The name of the Scaling Rule
* custom_rule_type - The Custom rule type. Possible values include: activemq, artemis-queue, kafka, pulsar, aws-cloudwatch, aws-dynamodb, aws-dynamodb-streams, aws-kinesis-stream, aws-sqs-queue, azure-app-insights, azure-blob, azure-data-explorer, azure-eventhub, azure-log-analytics, azure-monitor, azure-pipelines, azure-servicebus, azure-queue, cassandra, cpu, cron, datadog, elasticsearch, external, external-push, gcp-stackdriver, gcp-storage, gcp-pubsub, graphite, http, huawei-cloudeye, ibmmq, influxdb, kubernetes-workload, liiklus, memory, metrics-api, mongodb, mssql, mysql, nats-jetstream, stan, tcp, new-relic, openstack-metric, openstack-swift, postgresql, predictkube, prometheus, rabbitmq, redis, redis-cluster, redis-sentinel, redis-streams, redis-cluster-streams, redis-sentinel-streams, selenium-grid,solace-event-queue, and github-runner.
* metadata - A map of string key-value pairs to configure the Custom Scale Rule.
* authentication - Zero or more authentication blocks as defined below.
* secret_name - The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* http_scale_rule - One or more http_scale_rule blocks as defined below.
* name - The name of the Scaling Rule
* concurrent_requests - The number of concurrent requests to trigger scaling.
* authentication - Zero or more authentication blocks as defined below.
* secret_name - The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* tcp_scale_rule - One or more tcp_scale_rule blocks as defined below.
* name - The name of the Scaling Rule
* concurrent_requests - The number of concurrent requests to trigger scaling.
* authentication - Zero or more authentication blocks as defined below.
* secret_name - The name of the Container App Secret to use for this Scale Rule Authentication.
* trigger_parameter - The Trigger Parameter name to use the supply the value retrieved from the secret_name.
* revision_suffix - The suffix for the revision. This value must be unique for the lifetime of the Resource. If omitted the service will use a hash function to create one.
* termination_grace_period_seconds - The time in seconds after the container is sent the termination signal before the process if forcibly killed.
* volume - A volume block as detailed below.
* name - The name of the volume.
* storage_name - The name of the AzureFile storage.
* storage_type - The type of storage volume. Possible values are AzureFile, EmptyDir and Secret. Defaults to EmptyDir.

An identity block supports the following:
* type - The type of managed identity to assign. Possible values are SystemAssigned, UserAssigned, and SystemAssigned, UserAssigned (to enable both).
* identity_ids - - 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.

A secrets block supports the following:
* name - The secret name.
* identity - The identity to use for accessing the Key Vault secret reference. This can either be the Resource ID of a User Assigned Identity, or System for the System Assigned Identity.
* key_vault_secret_id - The ID of a Key Vault secret. This can be a versioned or version-less ID.
* value - The value for this secret.

A manual_trigger_config block supports the following:
* parallelism - Number of parallel replicas of a job that can run at a given time.
* replica_completion_count - Minimum number of successful replica completions before overall job completion.

A event_trigger_config block supports the following:
* parallelism - Number of parallel replicas of a job that can run at a given time.
* replica_completion_count - Minimum number of successful replica completions before overall job completion.
* scale - A scale block as defined below.
* max_executions - Maximum number of job executions that are created for a trigger.
* min_executions - Minimum number of job executions that are created for a trigger.
* polling_interval_in_seconds - Interval to check each event source in seconds.
* rules - A rules block as defined below.
* name - Name of the scale rule.
* custom_rule_type - Type of the scale rule.
* metadata - Metadata properties to describe the scale rule.
* authentication - A authentication block as defined below.
* secret_name - Name of the secret from which to pull the auth params.
* trigger_parameter - Trigger Parameter that uses the secret.

A schedule_trigger_config block supports the following:
* cron_expression - Cron formatted repeating schedule of a Cron Job.
* parallelism - Number of parallel replicas of a job that can run at a given time.
* replica_completion_count - Minimum number of successful replica completions before overall job completion.

Example output:
output "name" {
value = module.module_name.azurerm_container_app_job.name
}

Modules

No modules.

Additional Resources

For more details on configuring and managing Azure Container Apps and Azure Container App Jobs, refer to the Azure Container Apps Documentation and Azure Container Apps Jobs Documentation. This module manages Azure Container Apps and Container App Jobs, supporting secure networking, autoscaling, and event-driven workloads for microservices and task-based architectures.

Resources

Notes

  • Use Scale-to-Zero to optimize costs for idle or low-traffic workloads.
  • Apply event or schedule-based triggers using KEDA for dynamic job scaling.
  • Store sensitive data securely using environment secrets and managed identities.
  • Use revision-based traffic routing for safe rollouts and A/B testing.
  • Place apps in virtual networks to manage traffic flow and access control.
  • Monitor job runs and define retry and timeout settings for reliability.
  • Validate your Terraform configuration to ensure proper deployment of container resources.

License

This module is licensed under the MIT License. See the LICENSE file for more details.

About

This module manages Azure Container Apps and Jobs, enabling containerized tasks such as event-driven, scheduled, and manual jobs. It supports autoscaling, secure networking, and advanced configurations for microservices and serverless workloads.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages