You have your pod in the Azure Kubernetes Cluster (AKS) that should retrieve a secret in the Key Vault (NB: You must have created an instance within and uploaded the necessary secrets).
To allow the pod communication to an external secret managed solution, you must create -
- Secret Store CSI Driver
- Installation of the relevant provider that the driver has to talk to such as Hashicorp, Azure Key Vault etc.
- Integrate the AKS to the managed identity to allow connection to the azure key vault.
- To allow the specific pod to reach the key vault, a Service account for the pod has to be created and integrated with the managed identity.
Steps to setup the cluster and all needed requirements using CLI.
- Create Azure Resource Group
az group create --name keyvault-demo --location eastus
- Create an AKS cluster with Azure Key Vault provider for Secrets Store CSI Driver support
az aks create --name keyvault-demo-cluster -g keyvault-demo --node-count 1 --enable-addons azure-keyvault-secrets-provider --enable-oidc-issuer --enable-workload-identity
- Get the Kubernetes cluster credentials (Update kubeconfig)
az aks get-credentials --resource-group keyvault-demo --name keyvault-demo-cluster
- Verify that each node in your cluster's node pool has a Secrets Store CSI Driver pod and a Secrets Store Provider Azure pod running
kubectl get pods -n kube-system -l 'app in (secrets-store-csi-driver,secrets-store-provider-azure)' -o wide
Key vault creation and configuration
- Create a key vault with Azure role-based access control (Azure RBAC).
az keyvault create -n aks-demo-<_name of your choice_> -g keyvault-demo -l eastus --enable-rbac-authorization
NB: You may run into the below issue when using the above command for the first time.
Simply, check the registration state of your provide using the command below -
az provider show --namespace Microsoft.KeyVault --query registrationState
If it returns anything other than Registered, register it using the command -
az provider register --namespace Microsoft.KeyVault
Monitor the progress via
az provider show --namespace Microsoft.KeyVault --query registrationState
Wait until it shows: Registered
Then re-run the command-
az keyvault create -n aks-demo-<_name of your choice_> -g keyvault-demo -l eastus --enable-rbac-authorization
Connect your Azure ID to the Azure Key Vault Secrets Store CSI Driver.
- Configure workload identity:
export SUBSCRIPTION_ID=<your own subscription ID>
export RESOURCE_GROUP=keyvault-demo
export UAMI=<the name of your managed identity>
export KEYVAULT_NAME=<your keyvault name>
export CLUSTER_NAME=keyvault-demo-cluster
az account set --subscription $SUBSCRIPTION_ID
- Create a managed identity:
az identity create --name $UAMI --resource-group $RESOURCE_GROUP
export USER_ASSIGNED_CLIENT_ID="$(az identity show -g $RESOURCE_GROUP --name $UAMI --query 'clientId' -o tsv)"
export IDENTITY_TENANT=$(az aks show --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --query identity.tenantId -o tsv)
- Create a role assignment that grants the workload ID access the key vault.
export KEYVAULT_SCOPE=$(az keyvault show --name $KEYVAULT_NAME --query id -o tsv)
az role assignment create --role "Key Vault Administrator" --assignee $USER_ASSIGNED_CLIENT_ID --scope $KEYVAULT_SCOPE
- Get the AKS cluster OIDC Issuer URL This is necessary because to connect your service account of your kubernetes pod to the managed identity.
export AKS_OIDC_ISSUER="$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "oidcIssuerProfile.issuerUrl" -o tsv)"
echo $AKS_OIDC_ISSUER
- Create the service account for the pod
export SERVICE_ACCOUNT_NAME="workload-identity-sa"
export SERVICE_ACCOUNT_NAMESPACE="default"
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
azure.workload.identity/client-id: ${USER_ASSIGNED_CLIENT_ID}
name: ${SERVICE_ACCOUNT_NAME}
namespace: ${SERVICE_ACCOUNT_NAMESPACE}
EOF
- Setup Federation
export FEDERATED_IDENTITY_NAME="aksfederatedidentity"
az identity federated-credential create --name $FEDERATED_IDENTITY_NAME --identity-name $UAMI --resource-group $RESOURCE_GROUP --issuer ${AKS_OIDC_ISSUER} --subject system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}
- Create the Secret Provider Class
cat <<EOF | kubectl apply -f -
# This is a SecretProviderClass example using workload identity to access your key vault
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: azure-kvname-wi # needs to be unique per namespace
spec:
provider: azure
parameters:
usePodIdentity: "false"
clientID: "${USER_ASSIGNED_CLIENT_ID}" # Setting this to use workload identity
keyvaultName: ${KEYVAULT_NAME} # Set to the name of your key vault
cloudName: "" # [OPTIONAL for Azure] if not provided, the Azure environment defaults to AzurePublicCloud
objects: |
array:
- |
objectName: secret1 # Set to the name of your secret
objectType: secret # object types: secret, key, or cert
objectVersion: "" # [OPTIONAL] object versions, default to latest if empty
- |
objectName: key1 # Set to the name of your key
objectType: key
objectVersion: ""
tenantId: "${IDENTITY_TENANT}" # The tenant ID of the key vault
EOF
Verify Keyvault AKS Integration
- Create a sample pod to mount the secrets
cat <<EOF | kubectl apply -f -
# This is a sample pod definition for using SecretProviderClass and workload identity to access your key vault
kind: Pod
apiVersion: v1
metadata:
name: busybox-secrets-store-inline-wi
labels:
azure.workload.identity/use: "true"
spec:
serviceAccountName: "workload-identity-sa"
containers:
- name: busybox
image: registry.k8s.io/e2e-test-images/busybox:1.29-4
command:
- "/bin/sleep"
- "10000"
volumeMounts:
- name: secrets-store01-inline
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: secrets-store01-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "azure-kvname-wi"
EOF
- List the contents of the volume
kubectl exec busybox-secrets-store-inline-wi -- ls /mnt/secrets-store/
- Verify the contents in the file
kubectl exec busybox-secrets-store-inline-wi -- cat /mnt/secrets-store/secret1
Delete your setup
az group delete --name keyvault-demo













Top comments (0)