Publishing Helm 3 charts to Azure Container Registry using Azure DevOps - Part 1
Did you know you can publish Helm charts to an Azure Container Registry? It can be useful. Charts can be shared more easily with others or other business units. But also, when using a GitOps workflow, we can reference these Helm charts.
This is a quick guide on how to publish a Helm 3 chart to an Azure Container Registry.
Background
In Helm 2, you needed to install Tiller on your Kubernetes cluster in order to deploy Helm charts. Sure, there were other ways of using it too. With Helm 2, you could upload Helm charts to an Azure Container Registry. These charts could be tagged and versioned.
In Helm 3, there’s no more Tiller. That’s great! Makes things much simpler. We only need the client side tool.
There’s also a new standard for uploading artifacts to a container registry other than containers. The standard is Open Container Initiative (OCI) artifacts. In cloud native applications, applications are usually more involved than just container images. There’s Helm charts, there’s Terraform, maybe ARM, and other file-based artifacts.
If you’re curious about the background, there’s this great blog post from a Microsoft engineer.
Also, this blog post has been inspired by this doc from Microsoft.
Pre-Requisites
- An Azure Container Registry
- A service connection to an Azure Subscription
- A service connection to the container registry
First, you want to install Oras, a CLI tool for managing OCI artifacts.
- bash: |
set -e
curl -LO https://github.com/deislabs/oras/releases/download/v0.8.1/oras_0.8.1_linux_amd64.tar.gz
mkdir -p oras-install/
tar -zxf oras_0.8.1_*.tar.gz -C oras-install/
sudo mv oras-install/oras /usr/local/bin/
sudo rm -rf oras_0.8.1_*.tar.gz oras-install/
The first line set -e
forces the Bash script to fail the build in the event of an error.
Once Oras is installed, you want to authenticate against the Azure Container Registry. From the Microsoft guide, it states you have two options. Login through Azure CLI or straight through OCI. I prefer Azure CLI since I already have an Azure service connection.
- task: AzureCLI@2
displayName: Login to ACR
inputs:
azureSubscription: "$(Azure.ServiceConnection)"
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
az --version
az acr login --name $(ACR.Name)
Now, that you have Azure CLI installed, you are ready to issue commands to upload your OCI artifacts. I’m going to bash to showcase how to upload a dummy file.
- bash: |
echo "Here is an artifact!" > artifact.txt
oras push $(ACR.Name).azurecr.io/samples/artifact:$(Build.BuildNumber) \
--manifest-config /dev/null:application/vnd.unknown.config.v1+json \
./artifact.txt:application/vnd.unknown.layer.v1+txt
displayName: "Uploading dummy artifact"
This bash script creates a dummy file called artifact.txt
. Then it pushes it to a new repository on ACR. Most importantly, we’re able to tag it with the Build.BuildNumber
from the current build.
Here’s the end result.
Putting it all together
Here’s what my pipeline looks like.
variables:
ACR.Name: '[my registry name]'
ACR.ServiceConnnection: '[my registry service connection]'
Azure.ServiceConnection: '[my azure service connection]'
stages:
- stage: build
displayName: Build and Push
jobs:
- job: job_helm
displayName: Helm Publish
pool:
image: 'ubuntu-latest'
steps:
- bash: |
set -e
curl -LO https://github.com/deislabs/oras/releases/download/v0.8.1/oras_0.8.1_linux_amd64.tar.gz
mkdir -p oras-install/
tar -zxf oras_0.8.1_*.tar.gz -C oras-install/
sudo mv oras-install/oras /usr/local/bin/
sudo rm -rf oras_0.8.1_*.tar.gz oras-install/
displayName: "Install Oras"
- task: AzureCLI@2
displayName: Login to ACR
inputs:
azureSubscription: "$(Azure.ServiceConnection)"
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
az --version
az acr login --name $(ACR.Name)
- bash: |
echo "Here is an artifact!" > artifact.txt
oras push $(ACR.Name).azurecr.io/samples/artifact:1.0 \
--manifest-config /dev/null:application/vnd.unknown.config.v1+json \
./artifact.txt:application/vnd.unknown.layer.v1+txt
displayName: "Uploading dummy artifact"
That’s it! For the next part, I’ll upload a real helm chart.