OpenMCF logoOpenMCF

Loading...

Azure Container App

Deploys an Azure Container App within a Container App Environment, providing a fully managed serverless container platform with configurable containers, init containers, autoscaling (HTTP, TCP, Azure Queue, custom KEDA rules), ingress with traffic splitting, Dapr sidecar integration, secrets management, container registry authentication, managed identity, volumes, and health probes. This is the most feature-rich Azure component in OpenMCF.

What Gets Created

When you deploy an AzureContainerApp resource, OpenMCF provisions:

  • Container App -- a containerapp.App resource within the specified Container App Environment, configured with containers, scaling rules, ingress, secrets, and operational settings
  • Containers -- one or more application containers with configurable image, CPU, memory, environment variables, volume mounts, and health probes (liveness, readiness, startup)
  • Init Containers -- optional initialization containers that run to completion before application containers start
  • Ingress -- optional HTTP/TCP ingress with traffic weights, IP security restrictions, CORS policy, and mTLS
  • Scale Rules -- optional autoscaling via HTTP concurrent requests, TCP connections, Azure Queue length, or custom KEDA triggers
  • Dapr Sidecar -- optional Dapr integration for service invocation, pub/sub, state management, and bindings
  • Managed Identity -- optional SystemAssigned, UserAssigned, or both for credential-free Azure service authentication

Prerequisites

  • Azure credentials configured via environment variables or OpenMCF provider config
  • An Azure Container App Environment where the app will run (can reference an AzureContainerAppEnvironment resource)
  • Container images accessible from the specified registries -- public registries, ACR with credentials, or ACR with managed identity
  • An Azure Resource Group is not required directly -- the Container App inherits its resource group and region from the Container App Environment

Quick Start

Create a file containerapp.yaml:

apiVersion: azure.openmcf.org/v1
kind: AzureContainerApp
metadata:
  name: my-app
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: dev.AzureContainerApp.my-app
spec:
  resourceGroup: my-rg
  name: my-app
  containerAppEnvironmentId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my-rg/providers/Microsoft.App/managedEnvironments/my-env
  containers:
    - name: app
      image: mcr.microsoft.com/k8se/quickstart:latest
      cpu: 0.25
      memory: 0.5Gi
  ingress:
    external: true
    targetPort: 80

Deploy:

openmcf apply -f containerapp.yaml

This creates a Container App with a single container, external HTTP ingress on port 80, and Single revision mode.

Configuration Reference

Required Fields

FieldTypeDescriptionValidation
resourceGroupStringValueOrRefAzure Resource Group name. Can reference an AzureResourceGroup resource via valueFrom.Required
namestringContainer App name. Must be lowercase, hyphens allowed, 2-32 characters.Required, pattern ^[a-z][a-z0-9-]{0,30}[a-z0-9]$
containerAppEnvironmentIdStringValueOrRefContainer App Environment ID. Can reference an AzureContainerAppEnvironment resource via valueFrom.Required
containerslistApplication containers. At least one required. Each has name, image, cpu, memory.Minimum 1 item
containers[].namestringContainer name (required)Required
containers[].imagestringContainer image (required)Required
containers[].cpudoubleCPU cores (required, e.g., 0.25, 0.5, 1.0, 2.0)Required
containers[].memorystringMemory (required, e.g., 0.5Gi, 1Gi, 4Gi)Required

Optional Fields

FieldTypeDefaultDescription
revisionModestring"Single"Revision mode: Single (latest only) or Multiple (traffic splitting).
workloadProfileNamestring--Workload profile name for dedicated compute. Must match a profile in the environment.
maxInactiveRevisionsint--Maximum inactive revisions to retain.
minReplicasint--Minimum replicas (0 enables scale-to-zero).
maxReplicasint--Maximum replicas for autoscaling.
revisionSuffixstring--Custom suffix for the revision name.
containers[].envlist[]Environment variables with name and either value or secretRef.
containers[].probeslist[]Health probes (liveness, readiness, startup) with HTTP or TCP checks.
containers[].volumeMountslist[]Volume mounts with name and mountPath.
initContainerslist[]Init containers that run before app containers.
volumeslist[]Volumes: EmptyDir or AzureFile (with storage account and share).
httpScaleRuleslist[]HTTP autoscale rules with name and concurrentRequests.
tcpScaleRuleslist[]TCP autoscale rules with name and concurrentRequests.
azureQueueScaleRuleslist[]Azure Queue autoscale rules with name, queueName, queueLength.
customScaleRuleslist[]Custom KEDA autoscale rules with name, customRuleType, metadata.
secretslist[]Secrets: plain value or Key Vault reference (keyVaultUrl + identity).
registrieslist[]Container registries with server and authentication (username/password or identity).
ingressobject--Ingress configuration. See ingress fields below.
daprobject--Dapr sidecar with appId, appPort, appProtocol.
identity.typestring--Managed identity: SystemAssigned, UserAssigned, or SystemAssigned,UserAssigned.

Ingress fields:

FieldTypeDefaultDescription
externalboolfalseAllow traffic from outside the Container App Environment.
targetPortint--Port the container listens on (required when ingress is set).
transportstring"auto"Transport protocol: auto, http, http2, tcp.
exposedPortint--External port for TCP transport.
allowInsecureConnectionsboolfalseAllow HTTP traffic (disable HTTPS redirect).
trafficWeightslist[]Traffic weight rules for revision-based routing.
ipSecurityRestrictionslist[]IP-based access restrictions.
corsPolicyobject--CORS configuration with allowedOrigins, allowedMethods, allowedHeaders.

Examples

Web Service with HTTP Autoscaling

A web service with external ingress, HTTP-based autoscaling, and environment variables:

apiVersion: azure.openmcf.org/v1
kind: AzureContainerApp
metadata:
  name: web-service
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: prod.AzureContainerApp.web-service
spec:
  resourceGroup: prod-rg
  name: web-service
  containerAppEnvironmentId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/prod-rg/providers/Microsoft.App/managedEnvironments/prod-env
  minReplicas: 1
  maxReplicas: 10
  containers:
    - name: app
      image: myregistry.azurecr.io/myorg/web-service:v1.0.0
      cpu: 0.5
      memory: 1Gi
      env:
        - name: NODE_ENV
          value: production
        - name: DB_CONNECTION
          secretRef: db-conn
      probes:
        - type: liveness
          httpGet:
            path: /healthz
            port: 3000
          periodSeconds: 10
        - type: readiness
          httpGet:
            path: /ready
            port: 3000
  secrets:
    - name: db-conn
      value: "postgresql://..."
  registries:
    - server: myregistry.azurecr.io
      username: myregistry
      passwordSecretRef: acr-password
  ingress:
    external: true
    targetPort: 3000
  httpScaleRules:
    - name: http-scaling
      concurrentRequests: "50"

Background Worker with Queue Scaling

A background worker that scales based on Azure Queue depth:

apiVersion: azure.openmcf.org/v1
kind: AzureContainerApp
metadata:
  name: worker
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: prod.AzureContainerApp.worker
spec:
  resourceGroup: prod-rg
  name: queue-worker
  containerAppEnvironmentId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/prod-rg/providers/Microsoft.App/managedEnvironments/prod-env
  minReplicas: 0
  maxReplicas: 20
  containers:
    - name: worker
      image: myregistry.azurecr.io/myorg/worker:v2.0.0
      cpu: 1.0
      memory: 2Gi
      env:
        - name: QUEUE_CONNECTION
          secretRef: queue-conn
  secrets:
    - name: queue-conn
      value: "Endpoint=sb://..."
  azureQueueScaleRules:
    - name: queue-scaling
      queueName: work-items
      queueLength: 10
      authentications:
        - secretRef: queue-conn
          triggerParameter: connection

Enterprise API with Dapr and Identity

A production API with Dapr sidecar, managed identity, and IP restrictions:

apiVersion: azure.openmcf.org/v1
kind: AzureContainerApp
metadata:
  name: enterprise-api
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: prod.AzureContainerApp.enterprise-api
spec:
  resourceGroup: prod-rg
  name: enterprise-api
  containerAppEnvironmentId: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/prod-rg/providers/Microsoft.App/managedEnvironments/prod-env
  minReplicas: 2
  maxReplicas: 15
  identity:
    type: SystemAssigned
  containers:
    - name: api
      image: myregistry.azurecr.io/myorg/enterprise-api:v3.0.0
      cpu: 1.0
      memory: 2Gi
      probes:
        - type: liveness
          httpGet:
            path: /healthz
            port: 8080
        - type: startup
          httpGet:
            path: /ready
            port: 8080
          failureThreshold: 30
          periodSeconds: 2
  dapr:
    appId: enterprise-api
    appPort: 8080
    appProtocol: http
  ingress:
    external: true
    targetPort: 8080
    transport: http2
    corsPolicy:
      allowedOrigins:
        - "https://app.example.com"
      allowedMethods:
        - GET
        - POST
        - PUT
      allowCredentials: true
    ipSecurityRestrictions:
      - name: allow-office
        action: Allow
        ipAddressRange: 203.0.113.0/24

Using Foreign Key References

Reference OpenMCF-managed resources:

apiVersion: azure.openmcf.org/v1
kind: AzureContainerApp
metadata:
  name: ref-app
  labels:
    openmcf.org/provisioner: pulumi
    pulumi.openmcf.org/organization: my-org
    pulumi.openmcf.org/project: my-project
    pulumi.openmcf.org/stack.name: prod.AzureContainerApp.ref-app
spec:
  resourceGroup:
    valueFrom:
      kind: AzureResourceGroup
      name: my-rg
      field: status.outputs.resource_group_name
  name: ref-app
  containerAppEnvironmentId:
    valueFrom:
      kind: AzureContainerAppEnvironment
      name: my-env
      field: status.outputs.environment_id
  containers:
    - name: app
      image: mcr.microsoft.com/k8se/quickstart:latest
      cpu: 0.25
      memory: 0.5Gi
  ingress:
    external: true
    targetPort: 80

Stack Outputs

After deployment, the following outputs are available in status.outputs:

OutputTypeDescription
container_app_idstringAzure Resource Manager ID of the Container App
latest_revision_namestringName of the latest revision (e.g., {app}--{suffix})
latest_revision_fqdnstringFQDN of the latest revision, bypassing traffic splitting
outbound_ip_addressesstring[]Outbound IP addresses for firewall allowlisting
ingress_fqdnstringIngress FQDN (only set when ingress is configured). In Single mode, same as latest revision FQDN.

Related Components

  • AzureContainerAppEnvironment -- provides the hosting environment for the Container App
  • AzureResourceGroup -- provides the resource group
  • AzureUserAssignedIdentity -- provides managed identity for Key Vault and ACR access
  • AzureKeyVault -- stores secrets referenced by the Container App
  • AzureContainerRegistry -- hosts container images for the app

Next article

Azure Container App Environment

Azure Container App Environment Deploys an Azure Container Apps Managed Environment with optional VNet injection, internal load balancing, zone redundancy, Log Analytics integration, and dedicated workload profiles for GPU or guaranteed compute. The environment is the hosting boundary for Azure Container Apps -- all apps within it share the same virtual network, logging, and Dapr infrastructure. What Gets Created When you deploy an AzureContainerAppEnvironment resource, OpenMCF provisions:...
Read next article
Presets
3 ready-to-deploy configurationsView presets →