Import data to config map from kubernetes secret

yara mohamed picture yara mohamed · May 21, 2018 · Viewed 8.8k times · Source

I'm using a kubernetes ConfigMap that contains database configurations for an app and there is a secret that has the database password. I need to use this secret in the ConfigMap so when I try to add environment variable in the ConfigMap and specify the value in the pod deployment from the secret I'm not able to connect to mysql with password as the values in the ConfigMap took the exact string of the variable.

apiVersion: v1
kind: ConfigMap
metadata:
  name: config
data:
  APP_CONFIG: |
    port: 8080
    databases:
      default:
        connector: mysql
        host: "mysql"
        port: "3306"
        user: "root"
        password: "$DB_PASSWORD"

and the deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
  labels:
    app: backend
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: app
        image: simple-app-image
        ports:
          - name: "8080"
            containerPort: 8080
        env:
          - name: APP_CONFIG
            valueFrom:
              configMapKeyRef:
                name: config
                key: APP_CONFIG
          - name: DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: "mysql-secret"
                key: "mysql-root-password"

Note: the secret exist and I'm able to get "mysql-root-password" value and use to login to the database

Answer

Ignacio Millán picture Ignacio Millán · May 21, 2018

Kubernetes can't make that substitution for you, you should do it with shell in the entrypoint of the container.

This is a working example. I modify the default entrypoint to create a new variable with that substitution. After this command you should add the desired entrypoint.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
  labels:
    app: backend
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: app
        image: simple-app-image
        command:
          - /bin/bash
          - -c
        args:
          - "NEW_APP_CONFIG=$(echo $APP_CONFIG | envsubst) && echo $NEW_APP_CONFIG && <INSERT IMAGE ENTRYPOINT HERE>"
        ports:
          - name: "app"
            containerPort: 8080
        env:
          - name: APP_CONFIG
            valueFrom:
              configMapKeyRef:
                name: config
                key: APP_CONFIG
          - name: DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: "mysql-secret"
                key: "mysql-root-password"