Connect Azure Container Registry to Azure DevOps with Service Principal

The default experience of creating a service connection for an Azure Container Registry in Azure DevOps is functional but falls short if you are hoping to use an existing service principal.

Connect Azure Container Registry to Azure DevOps with Service Principal

Long title, but it gets the point across. The default experience of creating a service connection for an Azure Container Registry in Azure DevOps is functional but falls short if you are hoping to use an existing service principal. Specifically, in many organizations I've worked with, developers aren't granted permissions in AzureAD to create App Registrations and corresponding Service Principals.

In Azure DevOps, the dialogue for creating Docker Registry connections to ACR only presents an automated process that leverages the signed-in user's authorizations to discover and connect to container registries. No option is made available to use an existing service principal. Proceeding with that experience attempts to create a new app registration and will fail if the user doesn't have the requisite permissions in AAD.

ADO - Connect ACR

There is an alternative; connecting using the 'Others' generic connection dialogue. This option is intended to connect to any Docker Registry-compatible service.

ADO - Connect Generic Docker Registry

If you have an existing Service Principal/App Registration, ensure you've granted it the appropriate roles on your Azure Container Registry(AcrPush, AcrPull, etc.) You can now create your service connection in Azure DevOps.

Use the Client ID of your App Registration as the Docker ID and generate a secret to use as the Docker Password. Replace the URL for the Docker Registry with that of your ACR and give it a name and description.

ADO - Connect Generic Docker Registry - Filled

As simple as that.

You can use the Microsoft sample pipeline stage from this MS Docs article to test building and pushing images to Azure Container Registry.

- stage: Build
  displayName: Build and push stage
  jobs:  
  - job: Build
    displayName: Build job
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry:blogacr2022
        tags: |
          $(tag)
Mastodon