> ## Content Index
> Fetch the complete content index at: https://linuxhandbook.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to Store Helm Charts in Azure Container Registry
- URL: https://linuxhandbook.com/store-helm-charts-azure/
- Published: 2022-03-09T09:16:03.000Z
- Updated: 2024-02-27T12:30:25.000Z
- Description: Helm has a lot of awesome tools around it, but chart storage has always been an issue. Let's see how we can make the process a lot easier!
- Author: LHB Community
- Tags: DevOps

One of the great advantages of understanding how the container ecosystem works is that you can use the same pattern for several specifications.

It has not been long since, [Helm](https://helm.sh/?ref=linuxhandbook.com) announced that it would be supporting [OCI](https://opencontainers.org/?ref=linuxhandbook.com) Artifacts, which are nothing more than an OCI open specification for distributing container images and other types of data, called artifacts. 

This specification, like all other OCI specifications, is cloud-agnostic, which makes it a fantastic tool to work with.

## Container Records

A container record (CR), or a registry, is something that everyone who has ever had to be involved with containers has had to use. The CR is where we store our container images, so we can fetch them from anywhere and whenever we want.

In essence, an image is basically a set of files that follows a structure more or less like this:

```
 ├── blobs
       │   └── sha256
       │       ├── 1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db3...
       │       ├── 31fb454efb3c69fafe53672598006790122269a1b3b458607dbe106...
       │       └── 8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690f...
       ├── index.json
       └── oci-layout

```

The file `index.json` is the list of all the manifests available, that is, it is the list of all the images available in a location. In our case, it is a list of all the helm charts.

Each file inside `blobs/sha256`is a JSON that identifies an artifact, be it an image or a chart. This JSON is compliant with the [OCI specification](https://github.com/opencontainers/image-spec/blob/master/image-layout.md?ref=linuxhandbook.com#blobs) for SHA files.

In short, they are a list of settings describing the characteristics of the blob, its settings, properties, file system layers, and also the initial commands. 

In the case of a Helm Chart, we have the following file:

```json
{
  "schemaVersion": 2,
  "config": {
    "mediaType": "application/vnd.cncf.helm.config.v1+json",
    "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111",
    "size": 117
  },
  "layers": [
    {
      "mediaType": "application/tar+gzip",
      "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617",
      "size": 2487
    }
  ]
}

```

Notice that we have a differentiation of `mediaType`, while a common Docker image has a type `application/vnd.oci.image.config.v1+json`. 

Here, we have a type `application/vnd.cncf.helm.config`, the same goes for layers, each layer of an OCI image is of type `application/vnd.oci.image.layer.v1.tar+gzip`, while here we only have the format `.tar.gz`.

## Hosting charts in Azure Container Registry

Hosting Helm charts on Azure CR is pretty much similar to storing them locally. You need to have access to azure via Azure CLI. I'll assume you already have the [Azure CLI](https://docs.microsoft.com/cli/azure/install-azure-cli?WT.mc%5Fid=containers-20841-ludossan&ref=linuxhandbook.com), so let's create our ACR.

First we have to create our resource group and then the ACR with the commands:

```
az group create -n helm-reg -l eastus
az acr create -n chartregistry$RANDOM -g helm-reg --sku Basic -o tsv --query loginServer
```

A tip is to store the repository name in a variable:

```bash
export ACR=$(az acr create -n chartregistry$RANDOM -g helm-reg --sku Basic -o tsv --query loginServer)

```

Now we are going to log in to our registry using Azure managed keys, but we need to enable administrative control with `az acr update -n $ACR --admin-enabled true`. 

Next, run the following two commands to fetch the login credentials and save them in shell:

```bash
export ACRUSER=$(az acr credential show -n $ACR --query username -o tsv)
export ACRPASS=$(az acr credential show -n $ACR --query 'passwords[0].value' -o tsv)

```

Now we can log into our registry with Helm using `helm registry login $ACR --username $ACRUSER --password $ACRPASS`, and from here we already have our registry configured. 

Let's create another artifact with `helm chart save hrepo $ACR/hrepo:2.1.3` (as an example, I'll use a chart from a dumpy repository named hrepo). Then we'll push it with `helm chart push $ACR/hrepo:3.8.0`.

Once it's there, we'll be able to list everything in the repository with an Azure CLI command:

```bash
az acr repository show -n $ACR --repository hrepo

```

Notice that we are going to have an output that is exactly what we sent:

```json
{
  "changeableAttributes": {
    "deleteEnabled": true,
    "listEnabled": true,
    "readEnabled": true,
    "writeEnabled": true
  },
  "createdTime": "2022-03-05T20:56:49.6118202Z",
  "imageName": "hrepo",
  "lastUpdateTime": "2022-03-05T20:56:49.7812323Z",
  "manifestCount": 1,
  "registry": "chartregistry23657.azurecr.io",
  "tagCount": 1
}

```

We can also get more details with the command `show-manifests`by adding a `--detail`:

```bash
az acr repository show-manifests -n $ACR --repository hrepo --detail

```

This will give us exactly the definition of an OCI artifacts:

```bash
[
  {
    "changeableAttributes": {
      "deleteEnabled": true,
      "listEnabled": true,
      "quarantineState": "Passed",
      "readEnabled": true,
      "writeEnabled": true
    },
    "configMediaType": "application/vnd.cncf.helm.config.v1+json",
    "createdTime": "2022-03-05T20:56:49.7213057Z",
    "digest": "sha256:4780713fa23d7144d356c353795b5b84e66ad2b8bbd47c7118b4b85435d50bbc",
    "imageSize": 1378,
    "lastUpdateTime": "2022-03-05T20:56:49.7213057Z",
    "mediaType": "application/vnd.oci.image.manifest.v1+json",
    "tags": [
      "2.1.3"
    ]
  }
]

```

To store it, we have to simply:

```
helm chart pull $ACR/hrepo:3.8.0
helm chart export $ACR/hrepo:3.8.0 -d ./destination
helm install hrepo-acr ./destination
```

## Conclusion

Although using Helm is easy, yet there isn't a "simple" way to host a Helm chart as some kind of private record. 

While Helm has excellent tools like the [Chart Museum](https://github.com/helm/chartmuseum?ref=linuxhandbook.com), they are still not completely standard and for easy distributed development it is essential that we have open standards that everyone can as a whole can follow. 

Helm has recently moved OCI Registry support from experimental to general feature, which is a strong indication that the container ecosystem is becoming increasingly better.

✍️

****Author**: Talha Khalid is a freelance web developer and technical writer.