Standard Walkthrough

You will need Azure CLI installed and a Kubernetes cluster.

Run the following commands to set Azure-related environment variables and login to Azure via az login:

export SUBSCRIPTION_ID="<SubscriptionID>"
export TENANT_ID="<tenant id>"

# login as a user and set the appropriate subscription ID
az login
az account set -s "${SUBSCRIPTION_ID}"

export KEYVAULT_RESOURCE_GROUP=<keyvault-resource-group>
export KEYVAULT_LOCATION=<keyvault-location>
export KEYVAULT_NAME=secret-store-$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1)

1. Deploy Azure Key Vault Provider for Secrets Store CSI Driver

Deploy the Azure Key Vault Provider and Secrets Store CSI Driver components:

helm repo add csi-secrets-store-provider-azure
helm install csi csi-secrets-store-provider-azure/csi-secrets-store-provider-azure

Refer to installation for more details and validation.

2. Create Keyvault and set secrets

Create an Azure Keyvault instance:

  az group create -n ${KEYVAULT_RESOURCE_GROUP} --location ${KEYVAULT_LOCATION}
  az keyvault create -n ${KEYVAULT_NAME} -g ${KEYVAULT_RESOURCE_GROUP} --location ${KEYVAULT_LOCATION}

Add a secret to your Keyvault:

az keyvault secret set --vault-name ${KEYVAULT_NAME} --name secret1 --value "Hello\!"

3. Create an identity on Azure and set access policies

Refer to Identity Access Modes to see the list of supported modes for accessing the Key Vault instance.

In this walkthrough, we will be using the Service Principal auth mode for accessing the Key Vault instance we just created.

# Create a service principal to access keyvault
export SERVICE_PRINCIPAL_CLIENT_SECRET="$(az ad sp create-for-rbac --skip-assignment --name http://secrets-store-test --query 'password' -otsv)"
export SERVICE_PRINCIPAL_CLIENT_ID="$(az ad sp show --id http://secrets-store-test --query 'appId' -otsv)"

Set the access policy for keyvault objects:

az keyvault set-policy -n ${KEYVAULT_NAME} --secret-permissions get --spn ${SERVICE_PRINCIPAL_CLIENT_ID}

4. Create the Kubernetes Secret with credentials

Create the Kubernetes secret with the service principal credentials:

kubectl create secret generic secrets-store-creds --from-literal clientid=${SERVICE_PRINCIPAL_CLIENT_ID} --from-literal clientsecret=${SERVICE_PRINCIPAL_CLIENT_SECRET}
kubectl label secret secrets-store-creds

NOTE: This step is required only if you’re using service principal to provide access to Keyvault.

5. Deploy SecretProviderClass

Refer to section on the required and configurable parameters in SecretProviderClass object.

Create SecretProviderClass in your cluster that contains all the required parameters:

cat <<EOF | kubectl apply -f -
kind: SecretProviderClass
  name: azure-kvname
  namespace: default
  provider: azure
    usePodIdentity: "false"
    useVMManagedIdentity: "false"
    userAssignedIdentityID: ""
    keyvaultName: "${KEYVAULT_NAME}"
    objects: |
        - |
          objectName: secret1
          objectType: secret
          objectVersion: ""
    tenantID: "${TENANT_ID}"

6. Deployment and Validation

Create the pod with volume referencing the driver:

cat <<EOF | kubectl apply -f -
kind: Pod
apiVersion: v1
  name: busybox-secrets-store-inline
  - name: busybox
      - "/bin/sleep"
      - "10000"
    - name: secrets-store-inline
      mountPath: "/mnt/secrets-store"
      readOnly: true
    - name: secrets-store-inline
        readOnly: true
          secretProviderClass: "azure-kvname"
        nodePublishSecretRef:                       # Only required when using service principal mode
          name: secrets-store-creds                 # Only required when using service principal mode

To validate, once the pod is started, you should see the new mounted content at the volume path specified in your deployment yaml.

## show secrets held in secrets-store
kubectl exec busybox-secrets-store-inline -- ls /mnt/secrets-store/

## print a test secret held in secrets-store
kubectl exec busybox-secrets-store-inline -- cat /mnt/secrets-store/secret1

If successful, the output will be similar to:

kubectl exec busybox-secrets-store-inline -- ls /mnt/secrets-store/

kubectl exec busybox-secrets-store-inline -- cat /mnt/secrets-store/secret1