Search code examples
kubernetesaws-secrets-manager

Env variable from AWS Secrets Manager in Kubernetes


In EKS I am trying to use SecretProviderClass to provide secrets as environment variables to containers. I can see the secret mounted inside the container but no combination of key/names is allowing me to use it as an environment variable. Insode the container I can cat /mnt/secrets-store/awscredentials And see the output:

{"accesskey":"ABCDE12345","secretkey":"a/long/redacted5tring"}

My SecretProviderClass is below

apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: aws-secrets
  namespace: default
spec:
  provider: aws
  parameters:
    objects: |
        - objectName: "path/to/service/awscredentials"
          objectType: secretsmanager
          objectAlias: awscredentials
  secretObjects:
  - secretName: awscredentials
    type: Opaque
    data: 
    - objectName: accesskeyalias
      key: accesskey
    - objectName: secretkeyalias
      key: secretkey

and my deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myservice
  labels:
    team: devops
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myservice
  template:
    metadata:
      labels:
        app: myservice
    spec:
      serviceAccountName: myservice
      volumes:
      - name: secrets-store-inline
        csi:
          driver: secrets-store.csi.k8s.io
          readOnly: true
          volumeAttributes:
            secretProviderClass: "aws-secrets"
      containers:
      - name: myservice
        image: someimage:2
        volumeMounts:
        - name: secrets-store-inline
          mountPath: "/mnt/secrets-store"
          readOnly: true
        env:
        - name: AWS_ACCESS_KEY
          valueFrom:
            secretKeyRef:
              name: awscredentials
              key: accesskey

When I run the deployment without reference to the SecretKeyRef the container runs and I can see the secret under /mnt/secrets-store/awscredentials. However, trying to set the environment variable results in the pod stuck in Pending state and the message: Error: secret "awscredentials" not found I reckon I have mixed up the name and keys somewhere but I've spent hours trying every combination I can think of. What am I missing?


Solution

  • I eventually got this sorted. I had followed the AWS documentation for installing the driver which included using a helm chart i.e.

    helm install -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver
    

    However, the documentation failed to point out that with this helm chart you need to specifically set a value syncSecret.enabled=true - as in the code below.

    helm install -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --set syncSecret.enabled=true
    

    I used helm to uninstall the secrets-store-csi-driver, then re-installed with syncSecret.enabled=true and immediately my secretsmanager secret was available via kubectl get secrets -n default. So if you can see the secrets inside the container in the mounted volume but you can't set them as environment variables you should check that you installed with this value so that the k8s secret is created. Otherwise the secretObjects > secretName section is not actioned.