Create a secret provider class to serve secrets from Key Vault to your application
You now have everything in place to start using Key Vault secrets in your application code. You will need to create a secret provider class and update the YAML definition for the config microservice. You can use the below guidance to do so.
- Sync mounted content with a Kubernetes secret
- Set an environment variable to reference Kubernetes secrets
- Secrets Store CSI Driver ENV var
Step by step guidance
-
As a first step you will create a SecretProviderClass.
ADTENANT=$(az account show --query tenantId --output tsv) cat <<EOF | kubectl apply -n spring-petclinic -f - apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: azure-kvname-user-msi spec: provider: azure secretObjects: - secretName: gitpatsecret type: Opaque data: - objectName: gitpat key: gitpat parameters: usePodIdentity: "false" useVMManagedIdentity: "false" clientID: $USER_ASSIGNED_CLIENT_ID keyvaultName: $KEYVAULT_NAME cloudName: "" objects: | array: - | objectName: GIT-PAT objectType: secret objectAlias: gitpat objectVersion: "" tenantId: $ADTENANT EOFThis SecretProviderClass connects to your Key Vault and picks up the GIT-PAT Key Vault secrets This will get mapped to a secret object in your AKS cluster. The connection to Key Vault is made with the client ID of the user assigned managed identity you created in a previous step.
-
You can now update your YAML deployment definition to make use of this secret and map it to an environment variable for your pod. Navigate to the kubernetes directory and update the
spring-petclinic-config-server.ymlwith the contents from the spring-petclinic-config-server.yml file. You can again curl the updates for these files and then fill out the correct container registry name.curl -o spring-petclinic-config-server.yml https://raw.githubusercontent.com/Azure-Samples/java-microservices-aks-lab/main/docs/04_lab_secrets/spring-petclinic-config-server.yml IMAGE=${MYACR}.azurecr.io/spring-petclinic-config-server:$VERSION sed -i "s|#image#|$IMAGE|g" spring-petclinic-config-server.yml -
Inspect the new contents of the
spring-petclinic-config-server.ymlfile. This file has:- 1 additional environment variable that maps the
gitpatsecretsecret created by theSecretProviderClass. - An
azure.workload.identity/use: "true"so the pod can make use of the workload identity you configured. - A
serviceAccountName: workload-identity-sato indicate which service account the pod will be using. - An additional
volumesdefinition for creating a volume to the secret provider class. - An additional
volumeMountsdefinition to indicate where the volume needs to be mapped in the container.
We are not really using the volumes and volumeMounts elements, since your spring boot app will rely on environment variables. However these elements are needed so the secrets get loaded in your kubernetes cluster. In case you don’t define volumes and volumeMounts you will notice the secretProviderClass being present in the cluster but no additional secrets get created by it. This is because of how the Key Vault CSI driver works.
- 1 additional environment variable that maps the
-
You will also need to update the
application.ymlfile of theconfig-servermicroservice itself, so it does not make use of the hard-coded GitHub PAT token anymore. Navigate to the spring-petclinic-config-server/src/main/resources/application.yml file and update the password of the git repo to use theGIT_PATenvironment variable.password: ${GIT_PAT} -
Navigate to the root of the application and rebuild the
spring-petclinic-config-server.cd ~/workspaces/java-microservices-aks-lab/src mvn clean package -DskipTests -rf :spring-petclinic-config-server -
You will also have to rebuild the container image for the
config-server. Navigate to theacr-stagingdirectory, copy over the compiled jar file and rebuild the container.cd staging-acr rm spring-petclinic-config-server-$VERSION.jar cp ../spring-petclinic-config-server/target/spring-petclinic-config-server-$VERSION.jar spring-petclinic-config-server-$VERSION.jar docker build -t $MYACR.azurecr.io/spring-petclinic-config-server:$VERSION \ --build-arg ARTIFACT_NAME=spring-petclinic-config-server-$VERSION.jar \ --build-arg APP_PORT=8888 \ --build-arg AI_JAR=ai.jar \ . docker push $MYACR.azurecr.io/spring-petclinic-config-server:$VERSION -
Now re-apply the YAML file in your AKS cluster and wait for it to be properly up and running.
cd ../kubernetes kubectl apply -f spring-petclinic-config-server.yml kubectl get pods -w -
Once the config-server is properly up and running, escape out of the pod watch statement with
Ctrl+Q. Delete the pods of the customers, visits and vets microservices. This will make them restart and reload their configurationkubectl delete pod <customers-service-pod-name> kubectl delete pod <vets-service-pod-name> kubectl delete pod <visits-service-pod-name> -
You should see all your pods properly running again and data being shown in the spring petclinic application.
-
Once you redeployed the microservices, you can check that the secret kubernetes objects got created. In the output you will notice a _gitpatsecret_object.
kubectl get secrets -n spring-petclinic -
In case you see errors or crashloops of your pods, you can use the below statements to diagnose what might be going wrong. A first statement you can try is describe your pod.
kubectl describe pod <name-of-the-pod> -n spring-petclinicIn the output of the describe statement you should see your environment variables being mapped.
Environment: CONFIG_SERVER_URL: <set to the key 'CONFIG_SERVER_URL' of config map 'config-server'> Optional: false APPLICATIONINSIGHTS_CONNECTION_STRING: <set to the key 'APPLICATIONINSIGHTS_CONNECTION_STRING' of config map 'config-server'> Optional: false APPLICATIONINSIGHTS_CONFIGURATION_CONTENT: { "role": { "name": "config-server" } } GIT_PAT: <set to the key 'gitpat' in secret 'gitpatsecret'> Optional: false AZURE_CLIENT_ID: xxx AZURE_TENANT_ID: xxx AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/azure/tokens/azure-identity-token AZURE_AUTHORITY_HOST: https://login.microsoftonline.com/ -
In the logs of a pod you can see specific errors during startup
kubectl logs <name-of-the-pod> -n spring-petclinic -f -
You can also query the environment variables of your pod.
kubectl exec -it <name-of-the-pod> -n spring-petclinic -- envHere as well you should find back the GIT_PAT environment variable with the correct value.
-
And lastly, you can connect to the external service IP of the admin server on port 8080 to inspect whether your applications are properly running and what environment variables are loaded.