Step-by-Step Guide to Hosting a Helm Chart Repository on Azure Blob Storage

Ucheagwu OnyikeUcheagwu Onyike
5 min read

For this post, we will be using Azure Blob Storage to host the helm chart repo, and here are other requirements to get you set:

  • Helm, Azure CLI, and Terraform have been installed and are working.

  • A Helm chart (you can download any helm chart from any repo in its .tgz file format)

  • An understanding of Terraform (We will use this to provision the Azure storage blob service and upload the helm chart)

  • An Azure Storage Container SAS token

So here is a summary of the whole step: We will use Terraform to provision the resource group, storage account, and container and upload the blob (the helm chart’s index and .tgz file). We will then head to the Azure portal to get a SAS (shared access signature) token for the container that will be used, along with the container URL for authentication. We have a link to run “helm repo add” with the URL and the SAS.

Downloading A Helm Chart

Let’s download the Ngnix helm chart from Bitnami. Run the commands below to do that.

helm repo add bitnami https://charts.bitnami.com/bitnami

Note: You can use your own already packaged helm chart.

The next step is generating an “index.yaml” file using Helm.

Run the command below while in the same folder/path containing the downloaded/pulled Nginx helm chart or your custom helm chart.

helm repo index .

The command above is simply telling Helm to generate an index.yaml file in the current path - the dot means current folder.

Uploading The Helm Chart To Azure Blob Storage

Ensure that you have authenticated your local machine to your Azure portal—that way, Terraform can provision resources.
Follow this tutorial on Provisioning Azure Blob Storage using Terraformto see how to authenticate to the Azure Portal or type in;

az login

Now that we have the index.yaml file and a helm chart in .tgz file format, we can upload both files to Azure Blob.

We will use Terraform to achieve that, and the code for that is below.

#creates a resource group for the services below
resource "azurerm_resource_group" "demo-resource-group" {
  name     = var.resource_group_name
  location = var.resource_group_geolocation
}

#creates a storage account for your containers
resource "azurerm_storage_account" "demo-storage-account-tf" {
  name                     = var.storage_account_name
  resource_group_name      = azurerm_resource_group.demo-resource-group.name
  location                 = azurerm_resource_group.demo-resource-group.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

#creates a container to store your content
resource "azurerm_storage_container" "demo-storage-container-tf" {
  name                  = var.storage_container_name
  storage_account_name  = azurerm_storage_account.demo-storage-account-tf.name
  container_access_type = "private"
}

#uploads a file/blob into the above created container
resource "azurerm_storage_blob" "my-file-demo" {
  name                   = "index.yaml"
  storage_account_name   = azurerm_storage_account.demo-storage-account-tf.name
  storage_container_name = azurerm_storage_container.demo-storage-container-tf.name
  type                   = "Block"
  source                 = "index.yaml" #path to file
}

#uploads a file/blob into the created container
resource "azurerm_storage_blob" "my-file-demo" {
  name                   = "myhelmchart.tgz"
  storage_account_name   = azurerm_storage_account.demo-storage-account-tf.name
  storage_container_name = azurerm_storage_container.demo-storage-container-tf.name
  type                   = "Block"
  source                 = "myhelmchart.tgz"  #path to file
}

Create a “main.tf” file and paste the code above in it. Then, create a variable.tf file and paste the code below in it.

variable "resource_group_name" {
  default = "demoresourcegroupuche"
}

variable "resource_group_geolocation" {
  default = "West Europe"
}

#your storage account name has to be unique across all of Azure
variable "storage_account_name" {
  default = "demostorageaccountuche"
}

variable "storage_container_name" {
  default = "democontainernameuche"
}

Also, create a “providers.tf” file and paste the code below in it.

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.100.0"
    }
  }
}

provider "azurerm" {
  features {}
}

Run the following commands to get Terraform to provision the resources terraform init

terraform init
terraform plan

The command above shows you what Terraform is about to provision.

terraform apply

Terraform gives you another preview and awaits confirmation by typing “yes.”

Generating SAS Token

Once your resources are provisioned, use this command below to generate an SAS token.

az storage container generate-sas --account-name mystorageaccount --name mycontainer --permissions r --expiry 2024-05-02T00:00:00Z --https-only

Example:

az storage container generate-sas --account-name demostorageaccountuche --name democontainernameuche --permissions lr --expiry 2024-05-02T00:00:00Z --https-only

An SAS token is like this;

se=2024-05-02T00%3A00%3A00Z&sp=rl&spr=https&sv=2022-11-02&sr=c&sig=ZzT6GTfFzhpu/nugvI3tkYeuseYtR7y2wyiPlIfa/HI%3D

Another way to generate a SAS token is to go to the Azure portal.

  • Navigate to the Storage you created.

  • Click on the container in the side menu to list the containers under that storage account.

  • Click the three-dot menu on the container you want to generate a SAS token for and click on “Generate SAS token.”

  • Choose Read & List for the permission.

  • Select an expiry date and https only under “Allowed Protocols.”

Using SAS token to Create Helm Chart Repo URL

The template for any Azure Storage Container is as follows; note the last trailing backslash, right before the query string (?…), is very important.

https://<storage-account-name>.blob.core.windows.net/<container-name>/\?<SAS-token>

In our case, it will be;

https://demostorageaccountuche.blob.core.windows.net/democontainernameuche/\?se=2024-05-02T00%3A00%3A00Z&sp=rl&spr=https&sv=2022-11-02&sr=c&sig=ZzT6GTfFzhpu/nugvI3tkYeuseYtR7y2wyiPlIfa/HI%3D

One more thing.

Before you run “helm repo add myrepo <URL>,” bash will throw an error if you use the SAS token as is. So, we need to add the necessary escape backslash to the SAS token.

Using chatGPT, tell it to “Add the necessary backslash to this SAS token (paste in your SAS token).” You would have something like this;

se=2024-05-02T00\%3A00\%3A00Z\&sp=rl\&spr=https\&sv=2022-11-02\&sr=c\&sig=ZzT6GTfFzhpu/nugvI3tkYeuseYtR7y2wyiPlIfa/HI\%3D

Now, the correct URL for “helm repo add” will be like this;

https://demostorageaccountuche.blob.core.windows.net/democontainernameuche/\?se=2024-05-02T00\%3A00\%3A00Z\&sp=rl\&spr=https\&sv=2022-11-02\&sr=c\&sig=ZzT6GTfFzhpu/nugvI3tkYeuseYtR7y2wyiPlIfa/HI\%3D

You can then run the following command;

helm repo add mayazurehelmrepo https://demostorageaccountuche.blob.core.windows.net/democontainernameuche/\?se=2024-05-02T00\%3A00\%3A00Z\&sp=rl\&spr=https\&sv=2022-11-02\&sr=c\&sig=ZzT6GTfFzhpu/nugvI3tkYeuseYtR7y2wyiPlIfa/HI\%3D

You can run the following commands;

helm repo list #to list all your repos
helm search mayazurehelmrepo #to see all your charts in your repo
helm pull mayazurehelmrepo/<chart-name> #to pull down the chart from your repo

That is all. Please let me know your thoughts in the comments.

0
Subscribe to my newsletter

Read articles from Ucheagwu Onyike directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ucheagwu Onyike
Ucheagwu Onyike