Domain 1 β€” Module 5 of 8 63%
5 of 27 overall
Domain 1: Develop containerized solutions on Azure Free ⏱ ~13 min read

Azure Container Apps: Deploy + Revision Management

The serverless container service that scales from zero. Deploying images, managing revisions, traffic-splitting between revisions, secrets, and ingress configuration.

What Container Apps actually is

Simple explanation

Azure Container Apps is β€œI want containers, not Kubernetes.” Underneath, it IS Kubernetes β€” Microsoft runs the cluster β€” but you never see a node, a pod, a manifest, or kubectl. You give Azure a container image and a few rules (β€œscale from 0 to 50 when the queue grows”), and Azure runs it.

The defining feature is scale to zero. When nothing’s calling your AI inference endpoint, the cost is $0 β€” no idle replicas, no warm pool. When traffic arrives, KEDA wakes a replica in seconds.

The other defining feature is revisions. Every deploy creates a new immutable revision. You can split traffic across revisions (10% on the new model, 90% on the old) or roll back instantly by changing the active revision.

The hierarchy

Container Apps Environment (= shared VNet + log analytics)
β”œβ”€β”€ Container App: roo-vision-inference
β”‚   β”œβ”€β”€ Revision: roo-vision-inference--v3
β”‚   β”œβ”€β”€ Revision: roo-vision-inference--v3-1 (90% traffic)
β”‚   └── Revision: roo-vision-inference--v3-2 (10% traffic, new model)
β”œβ”€β”€ Container App: roo-orchestrator
└── Container App: roo-dashboard

Every change creates a revision. Whether traffic flows to it depends on your revision mode.

Revision modes β€” single vs multiple

Pick single revision unless you specifically need to canary across revisions.
FeatureSingle revision mode (default)Multiple revision mode
What it doesEach new revision becomes the only active one; old revisions deactivateMultiple revisions can be active simultaneously and serve traffic
Use forMost production apps β€” simple, ship-it-and-goBlue/green, canary, A/B testing across model versions
Switch withDefault β€” no extra config`az containerapp revision set-mode --mode multiple`
Traffic controlAlways 100% on latest revisionYou explicitly assign traffic % per revision
# Switch to multiple revision mode
az containerapp revision set-mode \
  --name roo-vision \
  --resource-group roo-prod \
  --mode multiple

# Send 90% to old, 10% to new
az containerapp ingress traffic set \
  --name roo-vision \
  --resource-group roo-prod \
  --revision-weight roo-vision--v3=90 roo-vision--v3-1=10
Real-world example: Mira's canary for a new vision model

Mira is shipping a new YOLO weights file. The old model has 18 months of warehouse data behind it; the new one is freshly fine-tuned. She can’t risk exposing every robot at once.

  1. Switch to multiple revision mode
  2. Deploy the new image (creates roo-vision--v3-2)
  3. Set traffic 95% old / 5% new
  4. Watch error rate, false-negative rate (objects missed) in Log Analytics
  5. Slowly shift traffic β€” 50/50 by day 3, 100% on new by day 7
  6. Deactivate the old revision once stable

If anything looks off mid-rollout, set old back to 100% β€” instant rollback, no redeploy, no image change.

Deploying β€” the minimal command

az containerapp create \
  --name roo-vision \
  --resource-group roo-prod \
  --environment roo-prod-env \
  --image roo.azurecr.io/roo-vision:v3.4.1 \
  --ingress external --target-port 8000 \
  --registry-server roo.azurecr.io --registry-identity system \
  --min-replicas 0 --max-replicas 30 \
  --env-vars LOG_LEVEL=info MODEL_NAME=phi-4-mini \
  --secrets openai-key=keyvaultref:https://roo-kv.vault.azure.net/secrets/OpenAIKey,identityref:system

That single command creates a public-facing inference endpoint that:

  • Scales from 0 to 30 replicas based on HTTP traffic
  • Pulls the image from ACR using the app’s managed identity (no password)
  • Reads the OpenAI key from Key Vault on every restart (no secret in the manifest)
  • Listens on port 8000

Ingress β€” how traffic gets in

Ingress modeVisibilityUse case
ExternalPublic internet via the environment’s *.<region>.azurecontainerapps.io hostPublic APIs, webhooks
InternalOnly reachable from inside the environment (or the integrated VNet)Backend services called by other container apps
DisabledNo HTTP ingressWorker containers triggered by queue messages, not HTTP

You also configure:

  • Target port β€” what your container listens on inside the replica
  • Transport β€” auto, HTTP/1.1, HTTP/2, or TCP (yes, Container Apps supports raw TCP for non-HTTP services)
  • Allow insecure β€” drop HTTPS-only enforcement (almost never needed; HTTPS is automatic)
  • Custom domains + managed certs β€” bring your domain, Azure provisions and renews the cert

Secrets β€” how Container Apps handles them

Container Apps has a first-class secrets concept distinct from environment variables.

# Define secrets at the app level
az containerapp secret set \
  --name roo-vision \
  --resource-group roo-prod \
  --secrets openai-key=keyvaultref:https://roo-kv.vault.azure.net/secrets/OpenAIKey,identityref:system \
            db-password=keyvaultref:https://roo-kv.vault.azure.net/secrets/DbPassword,identityref:system

# Reference secrets as env vars
az containerapp update \
  --name roo-vision --resource-group roo-prod \
  --set-env-vars OPENAI_API_KEY=secretref:openai-key DB_PASSWORD=secretref:db-password

Two secret styles:

StyleStored whereBest for
Inline valueEncrypted in the Container Apps platformSmall workloads, no Key Vault yet
Key Vault reference (keyvaultref:)Key VaultProduction. Rotation is a Key Vault edit; restart the revision to pick up the new value

Secrets are scoped to the container app. You reference them in env vars (secretref:openai-key) or in registry credentials.

Workload profiles β€” consumption vs dedicated

Container Apps environments have workload profiles β€” pools of compute the platform provisions on your behalf:

ProfileComputeScale to zeroBest for
ConsumptionMulti-tenant serverlessYesBursty workloads, low duty cycle, cost-sensitive
Dedicated D-seriesD-series VMs (4-32 vCPU)NoPredictable load, larger replicas, VM customisation
Dedicated NC-series GPUNC-series GPU SKUsNo (preview)GPU inference workloads

A single environment can hold multiple profile types. Container apps choose their profile per app.

# Deploy to a GPU profile
az containerapp create \
  --name roo-vision-gpu \
  --environment roo-prod-env \
  --workload-profile-name gpu-pool \
  --image roo.azurecr.io/roo-vision-cuda:v3.4.1

Logs and observability

Every container app environment is wired to a Log Analytics workspace. You query container output, system events, and KEDA scale events with KQL:

ContainerAppConsoleLogs_CL
| where ContainerAppName_s == "roo-vision"
| where TimeGenerated > ago(15m)
| where Log_s contains "ERROR"
| project TimeGenerated, RevisionName_s, Log_s
| order by TimeGenerated desc

KQL pieces you’ll see in Domain 4 are first-class for troubleshooting Container Apps.

Key terms

Question

What is a Container Apps revision?

Click or press Enter to reveal answer

Answer

An immutable snapshot of a container app's spec β€” image, env vars, scale rules, secrets, ingress. Every change to the spec creates a new revision. In single-revision mode the new revision replaces the old; in multiple-revision mode several can serve traffic simultaneously.

Click to flip back

Question

What's the difference between single and multiple revision mode?

Click or press Enter to reveal answer

Answer

Single (default) β€” only one revision is active at a time; new revisions take all traffic. Multiple β€” many revisions can be active and you assign traffic percentages between them. Use multiple for blue/green and canary deploys.

Click to flip back

Question

What are workload profiles in Container Apps?

Click or press Enter to reveal answer

Answer

Pools of compute attached to an environment: Consumption (serverless, scale-to-zero, multi-tenant), Dedicated D-series (single-tenant VMs), and GPU profiles. Each container app picks its profile, letting you mix bursty serverless workloads with predictable VM-backed ones in one environment.

Click to flip back

Question

How does Container Apps reference a Key Vault secret?

Click or press Enter to reveal answer

Answer

Define an app-level secret with `keyvaultref:` syntax pointing at the Key Vault secret URI plus an identity to read it. Reference the secret in env vars with `secretref:secret-name`. The platform resolves at startup; rotation is a Key Vault edit + revision restart.

Click to flip back

Question

What is the difference between external and internal ingress?

Click or press Enter to reveal answer

Answer

External ingress is reachable from the public internet via the environment's azurecontainerapps.io DNS. Internal ingress is reachable only from within the environment (or the integrated VNet) β€” useful for backend services that other container apps call.

Click to flip back

Knowledge check

Knowledge Check

Mira wants to ship a new vision model behind 5% canary traffic, then ramp to 100% over a week. Which Container Apps feature does she need?

Knowledge Check

Theo's clinical container app reads a database password from environment variable `DB_PASSWORD`. The password lives in Key Vault. What's the right Container Apps configuration?

Knowledge Check

Lin sets `--min-replicas 0 --max-replicas 10` on a Container App. The app idles for hours, then receives a single HTTP request. What happens?