Use Azure Key Vault Provider for Kubernetes Secrets Store CSI driver
Applies to: AKS on Azure Local 22H2, AKS on Windows Server
The Kubernetes Secrets Store CSI Driver integrates secrets stores with Kubernetes through a Container Storage Interface (CSI) volume. If you integrate the Secrets Store CSI Driver with AKS enabled by Azure Arc, you can mount secrets, keys, and certificates as a volume. The data is then mounted in the container's file system.
With the Secrets Store CSI driver, you can also integrate a key vault with one of the supported providers, such as Azure Key Vault.
Before you begin
Before you begin, make sure you have the following prerequisites:
- An Azure account and subscription.
- An existing deployment of AKS enabled by Arc with an existing workload cluster. If you don't have a deployment, follow this Quickstart for deploying an AKS host and a workload cluster.
- If you're running Linux clusters, they must be on version Linux 1.16.0 or later.
- If you're running Windows clusters, they must be on version Windows 1.18.0 or later.
- Make sure you've completed the following installations:
Access your clusters using kubectl
Run the following command to access your cluster using kubectl
. In the command, replace the value of -name
with your existing cluster name. You cluster name uses the specified cluster's kubeconfig
file as the default kubeconfig
file for kubectl
:
Get-AksHciCredential -name mycluster
Install the Secrets Store CSI driver
To install the Secrets Store CSI driver, run the following Helm command:
helm repo add csi-secrets-store-provider-azure https://azure.github.io/secrets-store-csi-driver-provider-azure/charts
The following command installs both the Secrets Store CSI driver and the Azure Key Vault provider:
helm install csi csi-secrets-store-provider-azure/csi-secrets-store-provider-azure --namespace kube-system
Note
You should install the Secrets Store CSI driver and Azure Key Vault provider in the kube-system
namespace. This guide uses the kube-system
namespace for all instances.
Verify the Secrets Store CSI driver and Azure Key Vault provider are successfully installed
Check your running pods to make sure the Secrets Store CSI driver and the Azure Key Vault provider are installed by running the following commands:
To verify the Secrets Store CSI driver is installed, run this command:
kubectl get pods -l app=secrets-store-csi-driver -n kube-system
Example output:
NAME READY STATUS RESTARTS AGE secrets-store-csi-driver-spbfq 3/3 Running 0 3h52m
To verify the Azure Key Vault provider is installed, run this command:
kubectl get pods -l app=csi-secrets-store-provider-azure -n kube-system
Example output:
NAME READY STATUS RESTARTS AGE csi-csi-secrets-store-provider-azure-tpb4j 1/1 Running 0 3h52m
Add secrets in an Azure key vault
You need an Azure Key Vault resource that contains your secret data. You can use an existing Azure Key Vault resource or create a new one.
If you need to create an Azure Key Vault resource, run the following command. Make sure you're logged in by running az login
with your Azure credentials. Then change the following values to your environment:
az keyvault create -n <keyvault-name> -g <resourcegroup-name> -l eastus
Azure Key Vault can store keys, secrets, and certificates. In the following example, a plain-text secret called ExampleSecret
is configured:
az keyvault secret set --vault-name <keyvault-name> -n ExampleSecret --value MyAKSHCIExampleSecret
Create an identity in Azure
Use a service principal to access the Azure Key Vault instance that you created in the previous step. You should record the outputs when running the following commands. You use both the client secret and client ID in the next steps.
Provide the client secret by running the following command:
az ad sp create-for-rbac --role Contributor --scopes /subscriptions/<subscription-id> --name http://secrets-store-test --query 'password' -otsv
Provide the client ID by running the following command:
az ad sp show --id http://secrets-store-test --query 'appId' -otsv
Provide the identity to access the Azure key vault
Use the values from the previous step to set permissions as shown in the following command:
az keyvault set-policy -n <keyvault-name> --secret-permissions get --spn <client-id>
Create the Kubernetes secret with credentials
To create the Kubernetes secret with the service principal credentials, run the following command. Replace the following values with the appropriate client ID and client secret from the previous step:
kubectl create secret generic secrets-store-creds --from-literal clientid=<client-id> --from-literal clientsecret=<client-secret>
By default, the secret store provider has filtered watch enabled on secrets. You can allow the command to find the secret in the default configuration by adding the label secrets-store.csi.k8s.io/used=true
to the secret:
kubectl label secret secrets-store-creds secrets-store.csi.k8s.io/used=true
Create and apply your own SecretProviderClass object
To use and configure the Secrets Store CSI driver for your Kubernetes cluster, create a SecretProviderClass
custom resource. Ensure the objects
array matches the objects you've stored in the Azure Key Vault instance:
apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
name: <keyvault-name> # The name of the Azure Key Vault
namespace: kube-system
spec:
provider: azure
parameters:
keyvaultName: "<keyvault-name>" # The name of the Azure Key Vault
useVMManagedIdentity: "false"
userAssignedIdentityID: "false"
cloudName: "" # [OPTIONAL for Azure] if not provided, Azure environment defaults to AzurePublicCloud
objects: |
array:
- |
objectName: <secret-name> # In this example, 'ExampleSecret'
objectType: secret # Object types: secret, key or cert
objectVersion: "" # [OPTIONAL] object versions, default to latest if empty
tenantId: "<tenant-id>" # the tenant ID containing the Azure Key Vault instance
Apply the SecretProviderClass to your cluster
To deploy the SecretProviderClass
you created in the previous step, use the following command:
kubectl apply -f ./new-secretproviderclass.yaml
Update and apply your cluster's deployment YAML file
To ensure that your cluster uses the new custom resource, update the deployment YAML file. For example:
kind: Pod
apiVersion: v1
metadata:
name: busybox-secrets-store-inline
spec:
containers:
- name: busybox
image: k8s.gcr.io/e2e-test-images/busybox:1.29
command:
- "/bin/sleep"
- "10000"
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "<keyvault-name>"
nodePublishSecretRef: # Only required when using service principal mode
name: secrets-store-creds # Only required when using service principal mode
Then, apply the updated deployment YAML file to the cluster:
kubectl apply -f ./my-deployment.yaml
Validate the Secrets Store deployment
To show the secrets that are held in secrets-store
, run the following command:
kubectl exec busybox-secrets-store-inline --namespace kube-system -- ls /mnt/secrets-store/
The output should show the name of the secret. In this example, it displays the following output:
ExampleSecret
To show the test secret held in secrets-store
, run the following command:
kubectl exec busybox-secrets-store-inline --namespace kube-system -- cat /mnt/secrets-store/ExampleSecret
The output should show the value of the secret. In this example, it shows the following output:
MyAKSHCIExampleSecret