Skip to main content Link Menu Expand (external link) Document Search Copy Copied

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.

Step by step guidance

  1. 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.

  2. 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
    
  3. 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 the SecretProviderClass.
    • 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.

  4. You will also need to update the application.yml file of the config-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 the GIT_PAT environment variable.

              password: ${GIT_PAT}
    
  5. 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
    
  6. You will also have to rebuild the container image for the config-server. Navigate to the acr-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
    
  7. 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
    
  8. 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 configuration

    kubectl delete pod <customers-service-pod-name> 
    kubectl delete pod <vets-service-pod-name> 
    kubectl delete pod <visits-service-pod-name> 
    
  9. You should see all your pods properly running again and data being shown in the spring petclinic application.

  10. 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
    
  11. 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/
    
  12. In the logs of a pod you can see specific errors during startup

    kubectl logs <name-of-the-pod> -n spring-petclinic -f
    
  13. 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.

  14. 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.