Home > Software engineering >  Getting AKV variables into an application with Secret Store CSI Driver
Getting AKV variables into an application with Secret Store CSI Driver

Time:03-19

Updating my CSI Secrets Store Driver as it is outlined here:

https://docs.microsoft.com/en-us/azure/aks/csi-secrets-store-driver

I had it previously working by usign secretObjects which I accomplished with:

apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: aks-akv-secret-provider
spec:
  provider: azure
  secretObjects:
  - secretName: myapp-prod-secrets
    type: Opaque
    data:
    - objectName: SENDGRID-API-KEY
      key: SENDGRID_API_KEY
  parameters:
    usePodIdentity: "true"                                        
    keyvaultName: myappakvprod
    cloudName: ""                               
    objects: |
      array:
        - |
            objectName: SENDGRID-API-KEY             
            objectType: secret                 
            objectVersion: ""  
    tenantId: $tenantId

In the manifest for the API for example I would:

...
  env:
    - name: SENDGRID_API_KEY
      valueFrom:
        secretKeyRef:
          name: myapp-prod-secrets
          key: SENDGRID_API_KEY
  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: aks-akv-secret-provider
...

And then in the code I would just do something like and it would work:

EMAIL_KEY = os.environ['SENDGRID_API_KEY']

Basically, it is mounting the AKV secrets to the Pod and then creating Kubernetes secret environmental variables.

However, this method in the documentation seems like an after thought ("You might sometimes..." as opposed to "you must"):

https://docs.microsoft.com/en-us/azure/aks/csi-secrets-store-driver#sync-mounted-content-with-a-kubernetes-secret

I interpret this as indicating that simply mounting the secrets to the Pod is sufficient and that creating Kubernetes secrets of them is extraneous.

My question is this:

If you are just mounting the secrets to the Pod, how should you access them from the application code if they aren't environmental variables?

They can be accessed with:

kubectl exec busybox-secrets-store-inline -- cat /mnt/secrets-store/ExampleSecret

So I'd imagine in Python, JavaScript, etc. you could do what ever the analogous command is to read in the secret instead of os.environ['ExampleSecret']. But if you aren't mounting secrets the same way in local development, there's disparity in the code base.

Just looking for clarification on this.

CodePudding user response:

If you just mount the secrets to the pod, the secrets will be available as files on the mount location

  • The filename will be the name of the secret (or an alias you specify in the secret provider class)
  • The content of the file will be the secret value.

To access and use the secrets in your code you would need to read the files to retrieve the secret values. Many frameworks have built in functionality for mapping such structures into configuration objects, for example in .NET there is the Key-per-file configuration provider

But if you aren't mounting secrets the same way in local development, there's disparity in the code base.

Yes that is correct, and would be true for anything you do different in development and production. If you want to avoid disparities, use the same mechanism for providing secret values to the application in both development and production, either through environment variables or through files.

  • Related