Azure Container Registry More Than Just an Image Store

John Kilmister, · 9 min read

In this Azure Back to School post, we’re going to take a look at the Azure Container Registry (ACR). It can be easy to assume that the ARC is a basic service that is just one of many components used when working with containers on Azure, however in this post we will look deeper at its many features and how to get more out of the service.

This post is part of the Azure Back to School series, and I would encourage you to look at the schedule for the rest of this year’s Azure Back to School sessions.

The Basics

Before we look at the more extended feature list let’s recap its basic features. If you have not used Azure Container Registry it holds both Linux and Windows tagged container images, along with associated assets. These can be exposed publicly or limited to private access via private endpoints.

Once stored images can be retrieved with Docker or any of the many Azure services that run containers. The ACR also has many features found in other Azure services such as Soft Delete, Managed Identities, Private End Points and Customer Managed Encryption Keys. Azure Container Registry comes in Basic, Standard, and Premium pricing tiers with a range of features at each tier. Each of these tiers are charged at a price per day and an additional charge if you go beyond the included storage.

OCI Artifacts

You could limit yourself to only building and pushing your container images, however ACR supports the Open Container Initiative standards. This means it can support artifacts beyond those you may create with a docker file. When working in Azure the most common OCI artifacts other than container images are Helm charts and Bicep Modules.

Helm charts V3, are used with the helm commands to apply changes to Kubernetes when pushed and are OCI compatible. If you are still using V2 helm charts, these cannot be made into an OCI format though can still pushed to an ACR. V2 charts are not displayed in the Azure portal and are deprecated with migration being recommended.

It is common to want to share Bicep modules between projects. We can now package up Bicep Modules in an OCI-compatible way, push them into the ACR. These can then be referenced in our bicep projects where they are pulled down into a local cache before being used.

No matter what type of artifact is pushed to the ACR all of the data is encrypted at rest.

ACR Tasks

The Azure Container Registry supports running both scheduled and one-off tasks. These can be used for a range of things from purging old images to building new images from docker files.

At this time ACR tasks have limited support in the Azure Portal beyond displaying schedules and logs. There is also no rest API. To create any tasks you must do this through the az CLI.

You can create the task using az acr task create. Then if you wish to run it outside a schedule you can use the command az acr task run to trigger it. These tasks can be viewed but not run or managed from the portal directly. The documentation has lots of examples should you wish to learn more.

All tasks are run on agents, much like a CI/CD process. You can use the built-in agents or if you want you can configure your own agent pools. These custom agents are in preview and beyond the scope of this post.

Overall the point of the tasks, are that they are designed to fit into the CI/CD build process.

Build Image Task

One of my most used ARC task commands is to build images from docker files, though you can also build directly from the source code.

It is always recommended to build an image on the same OS as the target container. This feature makes it easy to offload the building from your local machine or build agent to the ACR. I have done this on a linux machine when I needed to build a windows container image.

az acr login -n acrName

az acr build --image myImage:v1 \
  --registry acrName \
  --file Dockerfile . 

This command causes the files to be zipped and uploaded to the ACR where it will build the final image and deploy it to the registry.

There are many arguments you can pass including --no-wait to free your terminal, set --platform to configure the OS and other options to set the timeout. To go a step further, a new preview command az acr pack build allows you to also move the build of the code, if you are doing this outside of the container.

Although this feature is not tied to a particular pricing tier there is an additional cost per minute of building on top of the normal ACR pricing. This may be a consideration if you are comparing it to GitHub or Azure Pipelines.

Run CMD Task

We are seeing more maintenance features being built into the ACR feature set over time, however the ACR CMD gives us more options.

The az acr task create command allows you to run a custom command via the cmd parameter, something I frequently do. This could be used to run many different ACR commands but one of the most useful techniques is to use it to schedule the running of acr purge. I won’t go into the full detail here however there is a great blog post on automatically purging acr images using acr tasks. There are also many examples in the official documentation.

Frustratingly once the command is created I could not find a way to view it in full in the portal.

Run Image Task

It is possible to run an image directly from inside the ACR via a task. We can once again use the cmd parameter however pass the name of an image. The command will run the container and stream the output back to your terminal.

az acr run --registry acrName --cmd 'acrName/imageName:v1'

It is a simple mechanism however could be useful to run a scheduled task or just get some basic feedback for a one off task.

ACR Import

In addition to pushing images using any of the many commands, it is possible to import container images from another container registry. I have found this can be useful if you want to promote container images or any OCI artifact between a development and production ACR. It can also be used to perform an initial import if needed.

az acr import \
  --name acrName \
  --source docker.io/library/imageName:tagName \
  --image imageName:tagName
  --username <Docker Hub user name>
  --password <Docker Hub token>

It is worth noting you can prevent the export of images from your ACR if you are using a Premium tier registry. Unfortunately this ACR Import feature is not available for signed images.

Replication

In the recommended best practices for ACR, understandably it recommends creating your container registry in the same Azure region in which you deploy your containers. The reality is, however, that for disaster recovery your resources maybe located in many regions.

To resolve this, ACR supports enabling geo replication, although this is a Premium tier feature. Once enabled your images will be copied across all target regions and be accessible via a single endpoint. Premium charges are charged for each ACR, so this could be an expensive option depending on the number of locations.

Replication beyond Azure can now be done via a new Premium preview feature, Connected Registries. I am yet to use this however the documentation explains that “A connected registry is an on-premises or remote replica that synchronizes container images and other OCI artifacts with your cloud-based Azure container registry.” I can see this could be useful if you have a hybrid cloud setup or are using a multi-cloud strategy.

Alternatively if you are not on a Premium tier, to create copies you can push your images to multiple ACRs or use the ACR import feature to copy images between ACRs. Although this is not as convenient and you would have multiple host names and settings to manage access.

Security and Protection

The Azure container registry offers many of the standard features such as locking the resource from deletion, using managed identities, customer managed keys and soft delete. There are however, a few features just for working with images and OCI assets.

Tokens

It can be tempting to enable the Admin user from the Access Keys setting in the portal, providing a username and two passwords that you can cycle. This credentials give full admin access to the ACR which following the practice of least privilege is not ideal.

There is however another option in the form of Tokens. This Premium feature allows you to create permission scopes that group a set of read and write permission for content and/or meta-data. You can then apply these scopes to a sub-set of your repositories via a token.

A small note however, if you using signed images and wish to use the repository-scoped tokens they do not currently support pushing and pulling of signed images.

Locking Images

Once an image has been added to the registry we can lock it to prevent further writes to the same tag.

  az acr repository update \
    --name acrName --image imageName:v1 \
    --write-enabled false

It is also possible to lock the whole registry to prevent writing to any version of the container image. There are many variations and options all documented in the official documentation.

Signed Images

With content trust and signed images Premium feature it is possible to digitally sign your container images and use docker content trust for extra security.

Once enabled (via az acr config content-trust update or in the portal) you are will be able to push signed images. Consumers can then be set to only pulled signed images. This is a great way to ensure that the images you are running are the ones you expect and is supported by kubernetes.

Summary

We have only briefly covered a few of the key features of the Azure Container Registry. It is a powerful service that can be used for more than just storing container images. It can be used to store and manage a range of OCI artifacts, run tasks, import images, geo-replicate images, and comes with many other features.

Hopefully this post has inspired you to look deeper into the ACR and see how it can be used.

Title Photo by frank mckenna on Unsplash

Recent and Related Articles