1

I have an application in a container which reads certain data from a configMap which goes like this

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  application.yaml: |
        server:
          port: 8080
          host: 0.0.0.0

        ##
        ## UCP configuration.
        ## If skipped, it will default to looking inside of the connections.xml file.
        database:
            ApplicationDB:
                username: username
                password: hello123

Now I created a secret for the password and mounted as env variable while starting the container.

apiVersion: v1
kind: Secret
metadata:
  name: appdbpassword
type: Opaque
stringData:
  password: hello123

My pod looks like:

apiVersion: v1
kind: Pod
metadata:
  name: {{ .Values.pod.name }}
spec:
  containers:
    - name: {{ .Values.container.name }}
      image: {{ .Values.image }}
      command: [ "/bin/sh", "-c", "--" ]
      args: [ "while true; do sleep 30; done;"]
      env:
      - name: password
        valueFrom:
          secretKeyRef:
            name: appdbpassword
            key: password
      volumeMounts:
      - name: config-volume
        mountPath: /app/app-config/application.yaml
        subPath: application.yaml
  volumes:
    - name: config-volume
      configMap:
        name: app-config

I tried using this env variable inside the configMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  application.yaml: |
        server:
          port: 8080
          host: 0.0.0.0

        ##
        ## UCP configuration.
        ## If skipped, it will default to looking inside of the connections.xml file.
        database:
            ApplicationDB:
                username: username
                **password: ${password}**

But my application is unable to read this password. Am I missing something here?

EDIT:

I cannot change the application.yaml to any other form as my server looks for application.yaml in source path. Do we have any way to use that environment variable in values.yaml(helm) file and use it in the configmap?

Bhargav Behara
  • 285
  • 1
  • 4
  • 10

2 Answers2

1

your ${password} variable will not be replaced by its value as application.yaml is a static file. If you use this yaml file in some configuration then it is possible that it will get replaced by its value.

consider a scenario where instead of application.yaml pass this file

application.sh: |
       echo "${password}"

now go inside /app/app-config you will see application.sh file . And now do sh application.sh you will see the value of environment variable.

I hope this might clear your point.

shubham_asati
  • 623
  • 5
  • 14
  • I cannot change the application.yaml to any other form as my server looks for application.yaml in source path. Do we have any way to use that variable in values.yaml file and use it in the configmap? – Bhargav Behara Nov 28 '19 at 08:30
  • you can create a secret from application.yaml file.And then mount this secret to /app/app-config/application.yaml file – shubham_asati Nov 28 '19 at 08:59
  • or use [sed](https://stackoverflow.com/questions/584894/environment-variable-substitution-in-sed),[envsubst](https://unix.stackexchange.com/questions/294835/replace-environment-variables-in-a-file-with-their-actual-values) kind of tools to replace env var with their respective values.Add these command in postStart of a container. – shubham_asati Nov 28 '19 at 09:05
  • 1
    What you are doing is weird, and cumbersome. Passing a password from a secret to configmap is the same as putting it directly into a configMap. If your server is looking for the yaml file in that form, then your server is already configured wrong. Just start over, and do the things right. It will take you less time. – suren Nov 28 '19 at 10:27
1

You cannot use a secret in ConfigMap as they are intended to non-sensitive data (See here).

Also you should not pass Secrets using env's as it's create potential risk (Read more here why env shouldn't be used). Applications usually dump env variables in error reports or even write the to the app logs at startup which could lead to exposing Secrets.

The best way would be to mount the Secret as file. Here's an simple example how to mount it as file:

spec:
  template:
    spec:
      containers:
      - image: "my-image:latest"
        name: my-app
        ...
        volumeMounts:
          - mountPath: "/var/my-app"
            name: ssh-key
            readOnly: true
      volumes:
        - name: ssh-key
          secret:
            secretName: ssh-key

Kubernetes documentation explains well how to use and mount secrets.

acid_fuji
  • 6,287
  • 7
  • 22