In Kubernetes, Expose secrets in file as environment variables

5/3/2019

In Kubernetes, how can I expose secrets in a file (in a Kubernetes volume) as environment variables instead?

Background:
I followed the Google Cloud Platform GKE Vault Demo and in it, they show how to "continuously fetching a secret's contents onto a local file location. This allows the application to read secrets from a file inside the pod normally without needing to be modified to interact with Vault directly."

I would like to know how I can expose these secrets as environment variables (instead of a file) for the other application containers to use.

-- cryanbhu
hashicorp-vault
kubernetes

2 Answers

3/20/2020

Thanks @cryanbhu this actually saved me.

It is also possible to export all the variables without having to list them out:

command: ["/bin/bash", "-c"]  # you can also just use sh for other images
args:
  - source /etc/secrets/myproject/config;
    export $(cut -d= -f1 /etc/secrets/myproject/config);
    python3 my_app.py;

confirmed that works for me :)

-- wiherek
Source: StackOverflow

5/16/2019

I found out how to inject the secrets from the file into the application container.

First, the secrets file should be in the form KEY="VALUE" on each line.
For those using Consul Template to get the secrets from Vault, you can do it as such:

- name: CT_LOCAL_CONFIG
      value: |
        vault {
          ssl {
            ca_cert = "/etc/vault/tls/ca.pem"
          }
          retry {
            backoff = "1s"
          }
        }
        template {
          contents = <<EOH
        {{- with secret "secret/myproject/dev/module1/mongo-readonly" }}
        MONGO_READ_HOSTNAME="{{ .Data.hostname }}"
        MONGO_READ_PORT="{{ .Data.port }}"
        MONGO_READ_USERNAME="{{ .Data.username }}"
        MONGO_READ_PASSWORD="{{ .Data.password }}"
        {{- end }}
        {{- with secret "secret/myproject/dev/module2/postgres-readonly" }}
        POSTGRES_READ_HOSTNAME="{{ .Data.hostname }}"
        POSTGRES_READ_PORT="{{ .Data.port }}"
        POSTGRES_READ_USERNAME="{{ .Data.username }}"
        POSTGRES_READ_PASSWORD="{{ .Data.password }}"
        {{- end }}
        EOH
          destination = "/etc/secrets/myproject/config"
        }  

This will result in a secrets file in the correct KEY="VALUE" form.

From the secrets file, which is shared to the app container through volumeMount, we can inject the secrets as environment variables like this:

command: ["/bin/bash", "-c"]  # for Python image, /bin/sh doesn't work, /bin/bash has source
args:
  - source /etc/secrets/myproject/config;
    export MONGO_READ_HOSTNAME;
    export MONGO_READ_PORT;
    export MONGO_READ_USERNAME;
    export MONGO_READ_PASSWORD;
    export POSTGRES_READ_HOSTNAME;
    export POSTGRES_READ_PORT;
    export POSTGRES_READ_USERNAME;
    export POSTGRES_READ_PASSWORD;
    python3 my_app.py;  

In this way, we don't have to modify existing application code which expects secrets from environment variables (used to use Kubernetes Secrets).

-- cryanbhu
Source: StackOverflow