The seventh and last part of Azure Container Registry Unleashed is about housing Helm charts in ACR. This post explains how to use ACR as a protected Registry for Helm charts. We walk through the process of creating, publishing, and consuming a sample chart from ACR. However, if you have not used or seen Helm 3 before, consider reading my “Getting started with Helm 3” article first.

What Is OCI And What Are OCI artifacts

On top of Docker Registry 2.0, Azure Container Registry supports OCI artifacts. The OCI specification defines a general format for interchanging various artifacts like Docker Images or application bundles such as Helm charts. The official definition of OCI’s responsibility is

Established in June 2015 by Docker and other leaders in the container industry, the OCI currently contains two specifications: the Runtime Specification (runtime-spec) and the Image Specification (image-spec). The Runtime Specification outlines how to run a “filesystem bundle” that is unpacked on disk. At a high-level an OCI implementation would download an OCI Image then unpack that image into an OCI Runtime filesystem bundle. At this point the OCI Runtime Bundle would be run by an OCI Runtime.


If you want to dive deeper into OCI integration into Azure Container Registry, check out the ORAS (OCI Registry as Storage) project on GitHub.


Several tools and services have to be installed/provisioned and configured. Your Azure subscription should have the following services provisioned:

  • An instance of Azure Container Registry (ACR)
  • An instance of Azure Kubernetes Service (AKS)
    • The ACR instance should be attached to the AKS instance (read my previously published post, explaining 3 ways to attach ACR to AKS for further details on how to achieve that)

On your local development system, you should have installed and configured the following:

  • The Helm 3 CLI version 3.1.0 or later
  • The Azure CLI version 2.0.71 or later
  • The Kubernetes CLI kubectl with a proper context configuration pointing to the previously mentioned AKS instance

Authenticate Helm CLI Against ACR

To publish or push Helm charts to ACR, your local installation of helm has to establish an authenticated connection to ACR. In contrast to other Command-Line Interfaces, helm is not able to re-use the existing authentication token from Azure CLI. That said, you have to create a dedicated Service Principal and assign the role AcrPush to it. (Learn more about RBAC in the context of ACR by reading this part of the series).

# Create the Service Principal
az ad so create-for-rbac --name "acr-unleashed-helm" -o json
  "appId": "11111111-1111-1111-1111-111111111111",
  "displayName": "acr-unleashed-helm",
  "name": "http://acr-unleashed-helm",
  "password": "22222222-2222-2222-2222-222222222222",
  "tenant": "33333333-3333-3333-3333-333333333333"

# Grab the ACR Id
ACR_ID=$(az acr show -n unleashed --query id -o tsv)
# Create role assignment
az role assignment create --assignee $AZ_SP_ID --role AcrPush --scope $ACR_ID

Again, it is the Service Principal we just created, which is used to authenticate helm, to access ACR as a dedicated, protected chart registry. Assume that the password of the Service Principal is stored in the AZ_SP_PASSWD environment variable and the identifier in AZ_SP_ID.

# Add ACR (unique service name unleashed) as registry and
# provide the id and password from the Service Principal
echo $AZ_SP_PASSWD | helm registry login \
  -u $AZ_SP_ID --password-stdin

Enable OCI Support In Helm CLI

To enable OCI support in Helm 3, you have to set the HELM_EXPERIMENTAL_OCI environment variable to 1:

# Enable OCI Support in Helm 3

OCI support is currently flagged as experimental. Perhaps, this has changed in the meantime. Consult the official Helm documentation to verify.

Prepare Helm Charts For Publication On ACR

For demonstration purposes, let’s create a simple Hello World Helm chart, which we can use throughout this article to verify ACR can deal with custom Helm charts.

cd dev
helm create hello-acr

Before we can push the chart to ACR, we have to store it with a fully qualified name in Helm’s local registry cache. We can do so using the helm chart save command.

cd hello-acr
helm chart save .

At any point, you can use helm chart list to get a list of Helm charts stored in your local registry cache. (No worries we will delete the local version later)

Push A Helm Chart To ACR

Pushing a Helm chart to ACR is similar to pushing Docker images to ACR. We have logged in previously to access our custom registry, so all correctly qualified charts (those, starting with will automatically be routed to the corresponding registry by Helm CLI. Let’s give it a try.

helm chart push

The push refers to repository []
digest:  33c87247a4153cba103d7b965c1e08358205191ce9b6a68129e3005f84ab7541
size:    3.2 KiB
name:    hello-acr
version: 0.1.0
1.0.0: pushed to remote (1 layer, 3.2 KiB total)

Although Helm CLI confirms the push operation, you can also use the Azure Portal to verify. Just inspect the Repositories blade within your ACR instance.

Azure Container Registry - Our Helm chart in ACR

Pull A Helm Chart From ACR

We still have our Helm chart stored in the local registry cache. Delete it now using helm chart remove, because otherwise, Helm would not try to download it from ACR.

helm chart remove

1.0.0: removed

# verify chart is gone locally
helm chart list


Now we can pull it explicitly from ACR using the helm chart pull command.

helm chart pull

1.0.0: Pulling from
digest:  33c87247a4153cba103d7b965c1e08358205191ce9b6a68129e3005f84ab7541
size:    3.2 KiB
name:    hello-acr
version: 0.1.0
Status: Downloaded newer chart for

# verify the chart is locally available again
helm chart list

REF                                     NAME         VERSION    DIGEST     SIZE       CREATED    hello-acr    0.1.0      33c8724    3.2 KiB    26 minutes

Export Helm Chart Once Pulled

Since we pushed and now pulled the Helm chart as OCI artifact, we have to extract or export it for further usage. To export a chart, use helm chart export command as shown here:

helm chart export --destination ./chart-export

Deploy Helm Chart To AKS

Once you have successfully pulled a Helm chart from ACR, you can interact with it like with any other chart. Let’s quickly install the chart to kubernetes, verify it has been installed correctly, and then retract the chart again.

# get AKS credentials if you havent
az aks get-credentials -n aks-unleashed -g acr-unleahsed

# verify correct Kubernetes context
kubectl config set-context aks-unleashed

# create a namespace for demonstration purpose

kubectl create namespace acr-helm-demo

# navigate into the export folder of the chart
cd chart-export

# install the chart to the namespace
helm install acr-helm-demo-1 ./hell-acr -n acr-helm-demo

# verify release using Helm CLI
helm list -n acr-helm-demo -o yaml
- app_version: 1.16.0
  chart: hello-acr-0.1.0
  name: acr-helm-demo-1
  namespace: acr-helm-demo
  revision: "1"
  status: deployed
  updated: 2020-04-27 22:00:48.421724 +0200 CEST

# uninstall the release again
helm uninstall acr-helm-demo-1 -n acr-hello-demo

# delete namespace
kubectl delete ns acr-hello-demo

If you encounter an error while trying to install the Helm chart into Kubernetes, verify if your ACR instance is attached to AKS. If not, you can do so using the az aks update --attach-acr command.

Azure CLI Commands For Helm charts

The Azure CLI ships several commands to interact with Helm charts in the context of ACR. However, all sub-comamnds of az acr helm are targetting Helm 2.

To manage OCI artifacts in ACR using Azure CLI, you can use the regular commands such as az acr repository list or orthers.


I enjoy using Helm since they have removed the server-side component (Tiller). Being able to push and pull my Helm charts to and from Azure Container Registry is fantastic. Finally, ACR becomes the go-to resource for all my container-related distributable packages. If you have not looked into Helm as package-manager for your Kubernetes workloads, this is an additional argument why you should do so.

The ACR Unleashed series