Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The Azure Developer CLI (azd) supports deploying both Azure Container Apps and Azure Container App Jobs. For Azure Container Apps, azd offers two deployment strategies:
- Image-based strategy. Separates container app configuration updates from image deployments.
- Revision-based strategy. Combines both into a single deployment and supports advanced rollout patterns.
The following sections explain both strategies, along with how to deploy Container App Jobs.
Image-based deployment strategy
In this strategy, the container app configuration is created and updated during azd provision, while the container image is updated during azd deploy.
- The container app definition (resources, environment variables, health probes, and so on) resides in a Bicep module applied during provisioning.
- Only the container image reference (
containers[0].image) changes during deployment.
Revision behavior
Each change to the app configuration or image triggers a new revision:
| Step | Command | Applies changes to | Notes |
|---|---|---|---|
| 1 | azd provision |
Environment variables, resources, mounts, probes, load balancers | Creates a new revision |
| 2 | azd deploy |
Container image | Creates another revision |
Each revision allocates additional replicas in the Container Apps environment, which might temporarily increase resource usage and cost.
Note
Advanced rollout patterns, such as blue-green or canary, aren't supported in this strategy.
Configure image-based deployments
To ensure that azd provision updates an existing container app without overwriting the latest deployed image, perform an upsert operation. This pattern is implemented by the AVM container-app-upsert module and consists of two steps:
In your
main.parameters.json, define a parameter that references the azd-provided variableSERVICE_{NAME}_RESOURCE_EXISTS. This variable gets set automatically byazdat provision time to indicate whether the resource already exists.{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "environmentName": { "value": "${AZURE_ENV_NAME}" }, "location": { "value": "${AZURE_LOCATION}" }, // ... other parameters "apiExists": { "value": "${SERVICE_API_RESOURCE_EXISTS}" } } }In your Bicep file, reference the
existsparameter to control whether the container app should be created or updated. Thecontainer-app-upsertmodule encapsulates this logic internally.@description('Indicates whether the container app resource already exists.') param apiExists bool module api 'br/public:avm/ptn/azd/container-app-upsert:0.1.2' = { name: 'api' params: { name: 'my-api' location: location containerAppsEnvironmentName: containerAppsEnvironment.name containerRegistryName: containerRegistry.name imageName: !empty(apiImageName) ? apiImageName : '' exists: apiExists env: [ { name: 'MONGODB_CONNECTION_STRING' value: mongodb.outputs.connectionString } ] targetPort: 3100 } }This approach allows
azd provisionto upsert (update if exists, create if not) the container app resource safely without manual checks.Tip
Keep the
apiVersioninazure.yamlaligned with the Bicep module'sapiVersionforMicrosoft.App/containerAppsto avoid mismatches.
Revision-based deployment strategy
In this strategy, both the container app definition and image are deployed together during azd deploy.
The container app configuration resides in a dedicated Bicep module applied during deployment.
Changes to environment variables, images, resources, and load-balancing settings are rolled out as a single revision.
Tip
This strategy supports blue-green, canary, and other advanced rollout patterns.
Configure revision-based deployments
Define the container app deployment by creating an infra file for your service, such as
infra/api.bicep. You can define your container app by using the AVM-based module or by defining the resource directly:@description('Unique environment name used for resource naming.') param environmentName string @description('Primary location for all resources.') param location string param containerRegistryName string param containerAppsEnvironmentName string param imageName string param identityId string resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' existing = { name: containerRegistryName } resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2022-03-01' existing = { name: containerAppsEnvironmentName } module api 'br/public:avm/res/app/container-app:0.8.0' = { name: 'api' params: { name: 'api' ingressTargetPort: 80 scaleMinReplicas: 1 scaleMaxReplicas: 10 containers: [ { name: 'main' image: imageName resources: { cpu: json('0.5') memory: '1.0Gi' } } ] managedIdentities: { systemAssigned: false userAssignedResourceIds: [identityId] } registries: [ { server: containerRegistry.properties.loginServer identity: identityId } ] environmentResourceId: containerAppsEnvironment.id location: location tags: { 'azd-env-name': environmentName 'azd-service-name': 'api' } } }Provide parameters at deploy time by creating a parameters file (e.g.
api.parameters.json):{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "environmentName": { "value": "${AZURE_ENV_NAME}" }, "location": { "value": "${AZURE_LOCATION}" }, "containerRegistryName": { "value": "${AZURE_CONTAINER_REGISTRY_NAME}" }, "containerAppsEnvironmentName": { "value": "${AZURE_CONTAINER_ENVIRONMENT_NAME}" }, "imageName": { "value": "${SERVICE_API_IMAGE_NAME}" }, "identityId": { "value": "${SERVICE_API_IDENTITY_ID}" } } }Note
SERVICE_API_IMAGE_NAMEis dynamically set during deploy and isn't part of the provision outputs.When you run
azd deploy, the container app revision is applied using the resource definition above.Tip
Pass any additional outputs from
azd provisionas parameters toazd deployif your container app references other provisioned resources.
Comparison summary
| Aspect | Image-based | Revision-based |
|---|---|---|
| Update command | azd provision + azd deploy |
azd deploy only |
| Rollout type | Two revisions | Single revision |
| Rollout control | Managed by azd |
Configurable (blue-green, canary) |
| Use case | Simple environments | Advanced deployments |
| Container app definition location | Provision-time Bicep | Deploy-time Bicep |
Deploy Container App Jobs
In addition to Container Apps, azd supports deploying Azure Container App Jobs (Microsoft.App/jobs). Container App Jobs are designed for tasks that run to completion, such as batch processing, scheduled tasks, or event-driven work.
Note
Container App Jobs use the same host: containerapp setting in azure.yaml. No new host type is required. The Bicep template determines whether azd provisions a Container App or a Container App Job based on the resource type you define.
How it works
When azd discovers a job resource tagged with azd-service-name, it:
- Builds and pushes the Docker image to Azure Container Registry (same as Container Apps).
- Updates the job's container image by calling the Container App Jobs API instead of the Container Apps API.
- Returns empty endpoints, because jobs have no ingress.
Configure a Container App Job deployment
Define the
azure.yamlfile for your job service. Usehost: containerappandlanguage: docker:name: myapp services: job: host: containerapp language: docker project: ./src/job docker: path: ./Dockerfile context: .Create a Bicep module that provisions a
Microsoft.App/jobsresource. Tag the resource withazd-service-namesoazdcan discover it. The parameters and existing resource references (container registry, managed environment, identity) follow the same pattern as the Container Apps examples above:resource job 'Microsoft.App/jobs@2025-02-02-preview' = { name: 'job' location: location tags: { 'azd-env-name': environmentName 'azd-service-name': 'job' } properties: { environmentId: containerAppsEnvironment.id configuration: { replicaTimeout: 300 replicaRetryLimit: 1 triggerType: 'Manual' registries: [ { server: containerRegistry.properties.loginServer identity: identityId } ] } template: { containers: [ { image: imageName name: 'main' resources: { cpu: json('0.5') memory: '1.0Gi' } } ] } } identity: { type: 'UserAssigned' userAssignedIdentities: { '${identityId}': {} } } }Important
The
azd-service-nametag value must match the service name in yourazure.yamlfile. This tag is howazdassociates the provisioned resource with your service.Run
azd upto provision and deploy. The CLI automatically detects that the tagged resource is a Container App Job and handles the deployment accordingly.
Key differences from Container Apps
| Aspect | Container Apps | Container App Jobs |
|---|---|---|
| Resource type | Microsoft.App/containerApps |
Microsoft.App/jobs |
| Ingress/endpoints | Supports HTTP ingress | No ingress (empty endpoints) |
| Execution model | Long-running services | Run-to-completion tasks |
| Trigger types | Request-driven | Manual, scheduled, or event-driven |
Host setting in azure.yaml |
host: containerapp |
host: containerapp |