One of the last great features that Microsoft released few weeks ago is the possibility to get secrets into an Azure key Vault, from AKS, by using the Secret Store CSI (Container Storage Interface) Driver.
We already saw how to deploy an AKS cluster in previous articles.
To start we will check if the Key vault provider is already installed or not:
1 |
az aks show -g Starwind -n Starwind |
As you can see, the addon part is null. We will now start to deploy the provider to this existing cluster, by using Azure CLI:
1 |
az aks enable-addons --addons azure-keyvault-secrets-provider --name Starwind --resource-group Starwind |
If you have the error Invalid addon name, be sure that your azure cli version is at least in version 2.30.0. If not, do az upgrade to have the last version:
Some pods have been deployed into the AKS cluster, to be able to use the secret store CSI driver:
1 |
kubectl get pods -n kube-system |
A new User-Assigned managed identity has been created:
We will now create a new managed identity, for our app, App01. This app will need the access to the secret in our key vault, starwind-secret. You need to assign this identity to your VMSS, to be able to use it:
1 |
az identity create -g Starwind -n starwind-secret |
1 |
az vmss identity assign -g mc_starwind_starwind_westeurope -n aks-agentpool-26980127-vmss -- identities $(az identity show -g Starwind -n starwind-secret --query id -o tsv) |
We will now give access to this MI, to the right key vault. A get is sufficient. If you use Azure Role Based access control, it will be more fine grained accesses:
When it is done, we will create our secret store in our AKS environment, to be able to bind it after, into a pod. Here is the code to create it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# This is a SecretProviderClass example using user-assigned identity to access your key vault apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: azure-kvname-user-msi-starwind-secret spec: provider: azure parameters: usePodIdentity: "false" useVMManagedIdentity: "true" # Set to true for using managed identity userAssignedIdentityID: XXX-XXX-XXX # Set the clientID of the user-assigned managed identity to use keyvaultName: Starwind # Set to the name of your key vault cloudName: "" # [OPTIONAL for Azure] if not provided, the Azure environment defaults to AzurePublicCloud objects: | array: - | objectName: starwind-secret # Name of the secret that yo uwant to mount objectType: secret objectVersion: "" tenantId: xxx-xxx-xxx-xxx # The tenant ID of the key vault |
Apply now this template to AKS. The new provider is created:
We will now create a new pod, and try to mount this secret into it. I used a template provided by Microsoft to test the mount:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# This is a sample pod definition for using SecretProviderClass and the user-assigned identity to access your key vault kind: Pod apiVersion: v1 metadata: name: busybox-secrets spec: containers: - name: busybox image: k8s.gcr.io/e2e-test-images/busybox:1.29-1 command: - "/bin/sleep" - "10000" volumeMounts: - name: secrets-starwind mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-starwind csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "azure-kvname-user-msi-starwind-secret" |
Adapt values with yours, depending of the name that you gave for the secretProviderClass. Apply it:
We can now see in the mounted folder, that we have a secret mounted, and if we cat it, we have the value of it:
As you can see, it is a good way to give access to DEV to a value stored in a key vault (key, secret or certificate). The advantage here is that you can create a MI per app, per environment, and give accesses to a specific secret in a specific key vault. And all of this, without managing password and renewal of password.