azuredockerazure-devopsazure-pipelinesazure-container-registry

How to promote Docker images across multiple ACRs in Azure DevOps CI/CD pipelines?


I have a frontend and backend application, both running on Node.js, deployed using Docker. I have three environments: Dev, QA, and Prod, each with its own Azure Container Registry (ACR) and Azure App Service instance.

Current Setup:

The Docker images are only available in Dev ACR after the build pipeline. When the release pipeline runs, it fails for QA and Prod because those environments use separate ACRs (qaacr.azurecr.io, prodacr.azurecr.io).

I want a single build that can be deployed to all environments without rebuilding the image separately for each ACR.

How can I promote the Docker image from Dev ACR to QA and Prod ACRs in the release pipeline?

What is the best approach to deploy the same artifact across multiple environments?

Any best practices or suggestions would be greatly appreciated!


Solution

  • This is a common strategy. The dev registry can get bloated with daily builds, but the production registry only contains the images that were authorized for production use.

    Rather than rebuild the container image, as part of your deployment you can use the az cli to import the image from one registry to the other.

    - task: AzureCLI@2
      inputs:
        azureSubscription: serviceConnection
        addSpnToEnvironment: true
        scriptType: pscore
        scriptLocation: inlineScript
        inlineScript: |
    
          # determine if the image is already there
          $ErrorActionPreference = "SilentlyContinue"
          $image = az acr repository show `
                      --name $(registryName) `
                      --image $(imageName):$(imageVersion) 2>1
          $ErrorActionPreference = "Stop"
    
          # if the image wasn't found in the target registry
          if (!$image) {
            # import the image from source to target registry
            az acr import `
                 --name $(registryName) `
                 --source $(sourceRegistryName).azurecr.io/$(imageName):$(imageVersion) `
                 --image $(imageName):$(imageVersion)
          }