3

I am using azure key vault to save secrets and use as env variables in deployment.yaml.

but issue is I can see these secrets in azure kubernetes cluster in azure portal.

I read in kubernetes documentation that we can use these variables as file instead of env variables for more secure deployment.

What changes do I need do for achieving this

Here are my helm charts -

SecretProviderClass.yaml

apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
  name: azure-keyvault 
spec:
  provider: azure
  secretObjects:
  - secretName: database-configs
    type: Opaque
    data:
    - objectName: DB-URL
      key: DB-URL

  parameters:
    usePodIdentity: "false"
    useVMManagedIdentity: "true"
    userAssignedIdentityID: {{ .Values.spec.parameters.userAssignedIdentityID }} 
    resourceGroup: {{ .Values.spec.parameters.resourceGroup }} 
    keyvaultName: {{ .Values.spec.parameters.keyvaultName }} 
    tenantId: {{ .Values.spec.parameters.tenantId }} 
    objects: |
      array:
        - |
          objectName: DB-URL
          objectType: secret
          objectAlias: DB-URL

deployment.yaml

env:
          - name: DB-URL
            valueFrom:
              secretKeyRef:
                name: database-configs
                key: DB-URL
          volumeMounts:
          - mountPath: "/mnt/azure"
            name: volume
          - mountPath: "mnt/secrets-store"
            name: secrets-mount
            readOnly: true
      volumes:
        - name: volume
          persistentVolumeClaim:
            claimName: azure-managed-disk      
        - name: secrets-mount
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: "azure-keyvault"

file where helm substituting these values at deployment time-

settings.ini -

[server]
hostname = "localhost"
hot_deployment = false
url = "$env{DB-URL}"

[user_store]
type = "read_only_ldap"

Any help will be really appreciated.

I am looking for secure way to use key vault and kubernetes together

Srijit_Bose-MSFT
  • 1,010
  • 4
  • 13
megha
  • 621
  • 2
  • 11
  • 36

2 Answers2

1

I am still looking for a better answer, but this is what I tried.

Deployed a small dummy deployment with all secrets mapped to volume map and environment variable, matching with SecretProviderClass. This creates secrets in K8S.

Now deploying helmchart using those secrets works.

I know this is overhead to deploy unwanted things + it needs to be Highly Available. But could not find any workaround.

Looking for better answer!

Vishal
  • 774
  • 12
  • 27
0

The secrets appear in the Azure Portal Kubernetes Resource View because the SecretProviderClass azure-keyvault has spec.secretObjects field. In some cases, you may want to create a Kubernetes Secret to mirror the mounted content. Use the optional secretObjects field to define the desired state of the synced Kubernetes secret objects. Reference

Removing the spec.secretObjects will prevent the sync of mounted secret content with the AKS cluster.


An environment variable is a dynamic-named value that can affect the way running processes will behave on a computer. They are part of the environment in which a process runs. These should not be confused with files.

The Kubernetes documentation says that a secret can be used with a Pod in 3 ways:


I see that your Helm Chart already has the secret volume mount set up. That leaves the last step from here:

Modify your image or command line so that the program looks for files in the directory where your secrets would appear (in this case it looks like /mnt/secrets-store). Each key in the secret data map becomes the filename under mountPath.

Note: Assuming that you missed / in:

- mountPath: "mnt/secrets-store"
Srijit_Bose-MSFT
  • 1,010
  • 4
  • 13
  • Thanks for explaining this. Do you mean adding in deployment.yaml as - - mountPath: "mnt/secrets-store/DB-URL and doing this for every variable ? – megha Sep 21 '21 at 22:38
  • How do I call them from my settings.ini file ? Thank you – megha Sep 21 '21 at 22:39
  • 1
    You do not have to add `mountPath` for each file separately. The `mountPath`s set up in your deployment.yml would already mount each key from the secret in `/mnt/secrets-store`. – Srijit_Bose-MSFT Sep 22 '21 at 07:11
  • 1
    Since an [INI](https://en.wikipedia.org/wiki/INI_file) file is an informal standard, how you can reference other files or values from other files depends on the program which is using the configuration file. Assuming that said `settings.ini` file is part of the application, I would recommend you add the secret file path like `DB-URL-PATH = /mnt/secrets-store/DB-URL` and make the consumer program use text stream manipulation to fetch the secret value from `$DB-URL-PATH`, something like a `readLine()` etc. – Srijit_Bose-MSFT Sep 22 '21 at 07:20
  • 1
    In your `deployment.yml` I would say you need not add anything else. The `spec.volumes[1]` element and the corresponding `spec.containers[].volumeMounts[1]` are already defined in the `deployment.yml` to mount the secrets from `azure-keyvault` *SecretProviderClass* as files in `mnt/secrets-store` inside your resultant Pod. In your app's `INI` file you can set `DB-URL-PATH = mnt/secrets-store/DB-URL` and then the program consuming the configuration from said `INI` file can be modified to read the file whose path is stored in the `DB-URL-PATH` variable in the `INI` file to get the secret data. – Srijit_Bose-MSFT Sep 23 '21 at 07:38