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 EOF
This 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.yml
with 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.yml
file. This file has:- 1 additional environment variable that maps the
gitpatsecret
secret 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-sa
to indicate which service account the pod will be using. - An additional
volumes
definition for creating a volume to the secret provider class. - An additional
volumeMounts
definition 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.yml
file of theconfig-server
microservice 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_PAT
environment 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-staging
directory, 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-petclinic
In 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 -- env
Here 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.