wiki.getshifting.com

--- Sjoerd Hooft's InFormation Technology ---

User Tools

Site Tools


helmchartsecretprovider

Creating a Helm Chart for Azure SecretProvider

Summary: This wiki page shows how to create a helm chart for the Azure Secretprovider.
Date: 16 Janauray 2026

This is the wiki page on how the helm chart azure-secretprovider was created. The helm chart is used to create a SecretProviderClass manifest for AKS with workload identity enabled. After creating the chart and some example values file, I'll also show how to create a helm repository in Azure and how to publish the chart there. Finally, I'll also show an overview of how a secretprovider actually works in AKS with workload identity enabled.

Create a Helm Chart

Creating a Helm chart is very straightforward. If you already have a working environment with helm installed, you can simply run the following command to create a new chart:

helm create azure-secretprovider

This command will generate a directory structure for your Helm chart with some default files and folders. After that, and when looking at the documentation, the next step would be to remove all of the files and add your own. Now, creating a helm chart is very easy because all you need to do is adding a manifest file in the `templates` folder. That's all. Whenever you then do a helm install, it will just install that manifest. Of course, you can also use values, variables and more, which is what we'll do.

I used the following steps to create the chart, using the WSL installation I described earlier:

helm version
# Output: version.BuildInfo{Version:"v3.16.1", GitCommit:"5a5449dc42be07001fd5771d56429132984ab3ab", GitTreeState:"clean", GoVersion:"go1.22.7"}
helm create azure-secretprovider

A new folder is created called `azure-secretprovider`. After checking the files, I performed the following steps:

  • Removed the empty directory `charts`
  • Removed the directory `templates/tests`
  • Updated the Chart.yaml file with relevant information about the chart
  • From the `templates` folder, removed all files except for `_helpers.tpl` and `NOTES.txt`
    • Updated the `NOTES.txt` file with a link to this wiki page
  • Created a new file `secretproviderclass.yaml` in the `templates` folder
    • Created a template for the SecretProviderClass manifest, using values from `values.yaml`
  • Removed the content of the default `values.yaml` file and updated it with relevant parameters for the SecretProviderClass

Validate the Helm Chart

First, we can validate the chart using helm lint:

$ helm lint ./azure-secretprovider
==> Linting ./azure-secretprovider
 
1 chart(s) linted, 0 chart(s) failed

Next, we can generate an empty template using helm template:

$ helm template azure-secretprovider ./azure-secretprovider
---
# Source: azure-secretprovider/templates/secretproviderclass.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: azure-secretprovider
spec:
  provider: azure
  parameters:
    keyvaultName:
    objects: |
      array:
    tenantId:
    usePodIdentity: "false"
    clientID:

So far, everything looks good. Now, let's create some values files.

Values Files

I have created various values files for different use cases.

Grafana

The following values file creates two secrets, one for the Grafana admin credentials and one for the Grafana Slack Webhook. The first secret has two keys, while the second secret has one key:

tenantId: 7e4an71d-a123-a123-a123-abcd12345678
clientID: acc78f4a-932a-415f-a77e-e7e1071a0161
keyvaultName: kv-euw-shift
secrets:
  - Grafana-AdminPassword
  - Grafana-AdminUsername
  - Grafana-SlackWebHook
secretObjects:
  - secretName: grafana-admin
    data:
      - key: admin-password
        objectName: Grafana-AdminPassword
      - key: admin-user
        objectName: Grafana-AdminUsername
    type: Opaque
  - secretName: grafana-slackwebhook
    data:
      - key: SLACKWEBHOOK
        objectName: Grafana-SlackWebHook
    type: Opaque

If we would use this values file, we would render the following manifest:

$ helm template azure-secretprovider ./azure-secretprovider --values ./values/azure-secretprovider-grafana.yaml
---
# Source: azure-secretprovider/templates/secretproviderclass.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: azure-secretprovider
spec:
  provider: azure
  parameters:
    keyvaultName: kv-euw-shift
    objects: |
      array:
        - |
          objectName: Grafana-AdminPassword
          objectType: secret
        - |
          objectName: Grafana-AdminUsername
          objectType: secret
        - |
          objectName: Grafana-SlackWebHook
          objectType: secret
    tenantId: 7e4an71d-a123-a123-a123-abcd12345678
    usePodIdentity: "false"
    clientID: acc78f4a-932a-415f-a77e-e7e1071a0161
  secretObjects:
    - data:
      - key: admin-password
        objectName: Grafana-AdminPassword
      - key: admin-user
        objectName: Grafana-AdminUsername
      secretName: grafana-admin
      type: Opaque
    - data:
      - key: SLACKWEBHOOK
        objectName: Grafana-SlackWebHook
      secretName: grafana-slackwebhook
      type: Opaque

If needed, we could override one of the settings in the values file using --set: $ helm template azure-secretprovider ./azure-secretprovider --values ./values/azure-secretprovider-grafana.yaml --set keyvaultName=kv-euw-shift-dev

Certificate

The following values file creates a secret for a certificate:

secrets:
  - getshifting-tls-cert
  - getshifting-tls-key
secretObjects:
  - secretName: getshifting-tls
    data:
      - key: tls.crt
        objectName: getshifting-tls-cert
      - key: tls.key
        objectName: getshifting-tls-key
    type: kubernetes.io/tls

Creating a Helm Repository in Azure

To create a helm repository in Azure, we can use Azure Container Registry (ACR). ACR supports hosting helm charts, so we can push our chart to ACR and then use it as a helm repository. To create the repositor, we can go to Azure Cloud Shell and run the following commands:

# Variables
$project = "acrshift"
$rg = "rg-$project"
$loc = "westeurope"
# Create resource group
az group create `
  --name $rg `
  --location $loc
# Create Azure Container Registry
az acr create `
  --name "$project" `
  --resource-group $rg `
  --sku Basic `
  --location $loc `
  --public-network-enabled true

Push the Helm Chart to ACR

Now that we have created an Azure Container Registry, we can package our helm chart and push it to the ACR. Let's first package the chart:

helm package ./azure-secretprovider
Note that in the output of the command, you will see the path to the generated .tgz file. This is the file that we will push to ACR.

Next, we can push the chart to ACR. To do so, let's login to the ACR helm repository, amd then push the chart:

az login
# Make sure you're logged in to the correct subscription
az account set --subscription "30b3c71d-a123-a123-a123-abcd12345678"
# Login to ACR helm repository
USER_NAME="00000000-0000-0000-0000-000000000000"
ACR_NAME="acrshift"
PASSWORD=$(az acr login --name "$ACR_NAME" --expose-token --output tsv --query accessToken --only-show-errors)
echo "$PASSWORD" | helm registry login "$ACR_NAME.azurecr.io" --username $USER_NAME --password-stdin
# Push the chart to ACR
helm push azure-secretprovider-0.1.0.tgz oci://"$ACR_NAME".azurecr.io/helm

Using the Helm Chart from ACR

ER gaat van alles mis, aantekeningen:



/mnt/c/Repos/GetShifting/knowledge/drafts/helmchart (main)

note: helm repo add werkt niet omdat helm repo niet werkt met OCI registries

Once the chart is pushed to the ACRR, we can check the ACR for existing charts and view their manifests:

# List the helm charts in the ACR
$ az acr repository list --name $ACR_NAME
[
  "helm/azure-secretprovider"
]
# Show the details of the helm chart in the ACR
$ az acr repository show --name $ACR_NAME --repository helm/azure-secretprovider
{
  "changeableAttributes": {
    "deleteEnabled": true,
    "listEnabled": true,
    "readEnabled": true,
    "writeEnabled": true
  },
  "createdTime": "2026-02-06T16:32:05.1518971Z",
  "imageName": "helm/azure-secretprovider",
  "lastUpdateTime": "2026-02-06T16:32:05.3101879Z",
  "manifestCount": 1,
  "registry": "acrshift.azurecr.io",
  "tagCount": 1
}

To use the helm chart from ACR, we can add the ACR helm repository to our local helm client, and then install the chart from there:

# Add ACR helm repository
helm repo add "$ACR_NAME" oci://"$ACR_NAME".azurecr.io/helm
# Update helm repositories
helm repo update
# Install the chart from ACR using a local values file
$ helm template azure-secretprovider oci://$ACR_NAME.azurecr.io/helm/azure-secretprovider --values ./values/azure-secretprovider-grafana.yaml
Pulled: acrshift.azurecr.io/helm/azure-secretprovider:0.1.0
Digest: sha256:e10671232d69e5da0d662fd2c7bacfb621caf04a100d545334bf96b045d5315c
---
# Source: azure-secretprovider/templates/secretproviderclass.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: azure-secretprovider
spec:
  provider: azure
  parameters:
    keyvaultName: kv-euw-shift
    objects: |
      array:
        - |
          objectName: Grafana-AdminPassword
          objectType: secret
        - |
          objectName: Grafana-AdminUsername
          objectType: secret
        - |
          objectName: Grafana-SlackWebHook
          objectType: secret
    tenantId: 7e4an71d-a123-a123-a123-abcd12345678
    usePodIdentity: "false"
    clientID: acc78f4a-932a-415f-a77e-e7e1071a0161
  secretObjects:
    - data:
      - key: admin-password
        objectName: Grafana-AdminPassword
      - key: admin-user
        objectName: Grafana-AdminUsername
      secretName: grafana-admin
      type: Opaque
    - data:
      - key: SLACKWEBHOOK
        objectName: Grafana-SlackWebHook
      secretName: grafana-slackwebhook
      type: Opaque

As you can see from the 'Pulled' output, the chart is now pulled from the Azure Container Registry, and then together with the values file successfully rendered.

How does the SecretProviderClass work in AKS with Workload Identity Enabled

Now that we have created a helm chart for creating an Azure Secret Provider targeted on AKS with workload identity enabled, I also want to briefly show how the secretprovider works. Because of the workload identity and the central role of a secret provider, I created a diagram to show how the secretprovider works in AKS with workload identity enabled:

Secretprovider and workload identity overview


As you may note, the overview is for a secretprovider for grafana. This allowed for something extra, because in this setup grafana is also configured to use workload identity to access Azure monitor.

Note that the helm chart for Grafana is listed as a mix of the helm chart and the rendered manifest. This way it shows exactly what values are important for this setup.

This wiki has been made possible by:

helmchartsecretprovider.txt · Last modified: by 127.0.0.1