Accessing Key Vault with Secrets Store CSI Driver
Azure Key Vault Provider for Secrets Store CSI Driver are installed in all Gjensidige's AKS clusters. This enables a framework agnostic way of getting secrets stored in Azure Key Vault into your Kubernetes Pods. It also enables you to develop by the twelve-factor methodology which is widely accepted as best practise for building robust applications. We'll be accessing your team Key Vault using Azure AD Pod Identity.
Create and configure SecretProviderClass
Create a SecretProviderClass to configure access to your Key Vault and which secrets to fetch from that Key Vault:
- yaml
- app-template-libsonnet
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
namespace: "your-team-namespace"
name: "test-app-secrets"
labels:
app: "test-app"
spec:
provider: azure
secretObjects: # Create a Kubernetes Secret
- secretName: "your-secret-name" # Change this
type: Opaque
data:
- objectName: "your-keyvault-secret-name-1"
key: "your-keyvault-secret-name-1"
- objectName: "your-keyvault-secret-name-2"
key: "your-keyvault-secret-name-2"
parameters:
usePodIdentity: "true"
keyvaultName: "your-team-keyvault-name" # Change this
objects: |
array:
- |
objectName: "your-keyvault-secret-name-1"
objectType: secret
- |
objectName: "your-keyvault-secret-name-2"
objectType: secret
tenantId: "azure-tenant-id" # Change this
k8s_secretproviderclass:: {
enabled: true,
az_tenant:: "test",
keyvault: "your-team-keyvault-name",
secrets: [
{
objectName: "your-keyvault-secret-name-1",
key: "env-variable-name--can-be-same-as-your-keyvault-secret-name"
},
{
objectName: "your-keyvault-secret-name-2",
key: "env-variable-name--can-be-same-as-your-keyvault-secret-name"
},
],
},
Mount secrets into your Deployment
Configure your Deployment configuration to get secrets mounted into your Pod:
- yaml
- app-template-libsonnet
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: "your-team-namespace"
name: "test-app"
labels:
app: "test-app"
spec:
selector:
matchLabels:
app: "test-app"
template:
metadata:
name: "test-app"
labels:
aadpodidbinding: "your-team-pod-identity" # [1]
app: "test-app"
spec:
containers:
- name: "test-app"
image: "gjensidige.azurecr.io/test-app:12345"
env:
- name: "YOUR_SECRET_ENV_VAR_1" # [4]
valueFrom:
secretKeyRef:
name: "your-secret-name"
key: "your-keyvault-secret-name-1"
volumeMounts:
- name: "secrets-store-inline" # [3]
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: "secrets-store-inline" # [2]
csi:
driver: "secrets-store.csi.k8s.io"
readOnly: true
volumeAttributes:
secretProviderClass: "test-app-secrets"
The template by default mounts and sets the env for the specified secrets.
- Azure AD Pod Identity is used to access the Key Vault. This must be set to your team Pod Identity.
- Use the Secrets Store CSI driver to add a Volume containing secrets defined in
SecretProviderClassto your Pod - Mount the Volume to your Pod file system at
/mnt/secrets-store - [Optional] This step is only needed if you want your secret exposed as an environment variable.
secretObjectsmust be configured inSecretProviderClassfor this to work. Remember to update "your-secret-name". You can also useenvFromwithsecretReffor cleaner syntax as described here
Find multiple other usage examples in the secrets-store-csi-driver-provider-azure GitHub repo
Verify configuration
Get all pods in your namespace:
kubectl get pods -n your-team-namespace
Select correct pod and verify that secrets are mounted into /mnt/secrets-store as defined in the Deployment yaml above:
kubectl exec pod/your-pod-name -n your-team-namespace -- ls /mnt/secrets-store
If you also added secrets to environment variables, you can use the following command to run echo inside your pod to verify that a secret exists:
kubectl exec pod/your-pod-name -n your-team-namespace -- sh -c 'echo $YOUR_SECRET_ENV_VAR'
Adding or updating secrets
If you are creating Kubernetes secrets with secretObjects in SecretProviderClass, the secrets are auto synced with Azure Key Vault every 2 minutes. An alternative to waiting 2 minutes is to delete the secret resource in your namespace and restarting the pod.