Skip to content

Roll back a deployment

A bad deploy is live and you want the previous version back. There are two ways, and picking the right one matters:

  • Pin ingress to a known-good revision — fast, in-place, no rebuild. Restores the image only. Use it when the code is bad but config is unchanged.
  • Redeploy a known-good commit — the pipeline rebuilds from source and re-applies env from the org variables/secrets. Slower, but it also unwinds config drift. Use it when the bad deploy also changed an org variable, a secret, or an env-var name.

Every service deploys through the shared engine described in the CI/CD pipeline; rollback is just its two exits. Names and shapes only below — never paste a secret value.

  1. Have the Azure CLI installed and authenticated as the deploy identity (the AZURE_CREDENTIALS service principal, or your own az login with rights on the resource group).

  2. Know the exact app name and resource group. The fleet’s naming is by convention: the app is <service>-staging or <service>-prod, and everything lives in resource group rg-core, ACA environment env-soundverse-core. Examples below use core-gateway-consumer-staging; swap in your app.

Option A — Pin traffic to a known-good revision

Section titled “Option A — Pin traffic to a known-good revision”
fast, image-only

Each deploy creates a new ACA revision. Rolling back is a matter of sending 100% of ingress traffic to a healthy older one.

  1. List revisions, newest first, and identify a good one by its image tag (the image is tagged with the commit SHA):

    find a good revision
    az containerapp revision list \
    -n core-gateway-consumer-staging -g rg-core \
    --query "[].{name:name,active:properties.active,created:properties.createdTime,image:properties.template.containers[0].image}" \
    -o table
  2. Switch to multiple revision mode so traffic can be split/pinned:

    enable traffic pinning
    az containerapp revision set-mode \
    -n core-gateway-consumer-staging -g rg-core \
    --mode multiple
  3. Activate the good revision (a deploy may have deactivated it), then send it all traffic:

    pin 100% traffic to the good revision
    az containerapp revision activate \
    -n core-gateway-consumer-staging -g rg-core \
    --revision core-gateway-consumer-staging--good0001
    az containerapp ingress traffic set \
    -n core-gateway-consumer-staging -g rg-core \
    --revision-weight core-gateway-consumer-staging--good0001=100
clean, config-safe

This re-runs the full pipeline: fresh image build and a re-collection of the STAGING_/PROD_ org variables and secrets. It is the correct choice whenever the bad deploy also touched configuration — a revision pin restores only the container image, not an org-variable or secret change.

  1. Move the deployment branch back to the good commit. The pipeline deploys the tip of staging / prod, so a revert of the branch is the redeploy. Prefer a git revert (keeps history); use a hard reset only when you must:

    revert the bad change (preferred)
    git checkout staging
    git revert <bad-sha> # or: git reset --hard <good-sha>
    git push origin staging # add --force-with-lease if you reset
  2. Or trigger an off-cycle run without moving the tip (deploys whatever staging currently points at):

    off-cycle deploy + watch
    gh workflow run deploy-aca-staging.yml --ref staging
    gh run watch
  3. Verify the new revision came up healthy and that the live env is what you expect — read the running container’s env (secret-injected vars show as secretRef, not values):

    confirm the rolled-back config
    az containerapp show \
    -n core-gateway-consumer-staging -g rg-core \
    --query "properties.template.containers[0].env"

    See Inspect a running service for what that output means.