Home > Software engineering >  How to reuse K8s container environment variables in other containers using helm?
How to reuse K8s container environment variables in other containers using helm?

Time:09-09

I have a deployment with a pod that has his configuration defined through a lot of environment variables. Now I want to add a sidecar container that requires exactly the same environment variables as the already defined container. Instead of just copy/pasting all the variables I'd like to stick to the DRY principle.

The current definition looks something like this:

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: container1
        env:
        - name: MYSQL_HOST
          value: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }}
        - name: MYSQL_DATABASE
          value: {{ .Values.mariadb.auth.database | quote }}
        - name: MYSQL_USER
          valueFrom:
            secretKeyRef:
              name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }}
              key: {{ .Values.usernameKey | default "db-username" }}
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }}
              key: {{ .Values.passwordKey | default "db-password" }}

The recommended way to reuse environment variables is through a ConfigMap. Now I can create this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: config
data:
  MYSQL_HOST: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }}
  MYSQL_DATABASE: {{ .Values.mariadb.auth.database | quote }}
---
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: container1
        envFrom:
        - configMapRef:
            name: config
      - name: container2
        envFrom:
        - configMapRef:
            name: config

But now I would still need to repeat myself for MYSQL_USER and MYSQL_PASSWORD (and for the 20 other env variables that are like this).

Is it possible to reuse the existing secrets MYSQL_USER and MYSQL_PASSWORD as environment variables without creating duplicates on container1 and container2?

CodePudding user response:

You can do the same thing but mount a secret:

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: secret
stringData:
  MYSQL_USER: {{ .Values.usernameKey | default "db-username" }}
  MYSQL_PASSWORD: {{ .Values.passwordKey | default "db-password" }}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: config
data:
  MYSQL_HOST: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }}
  MYSQL_DATABASE: {{ .Values.mariadb.auth.database | quote }}
---
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: container1
        envFrom:
        - configMapRef:
            name: config
        - secretRef:
            name: secret
      - name: container2
        envFrom:
        - configMapRef:
            name: config
        - secretRef:
            name: secret

CodePudding user response:

You can create a named template to do this. If you're only going to be using this template within a single Kubernetes object (multiple containers within the same Deployment) you could put it in that object's deployment.yml file, or into the shared _helpers.tpl file.

{{- define "env.mysql" -}}
- name: MYSQL_HOST
  value: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }}
- name: MYSQL_DATABASE
  value: {{ .Values.mariadb.auth.database | quote }}
- name: ET
  value: cetera
{{- end -}}

Then wherever you need to use that block of variables, you can include it, and indent it to the correct level.

spec:
  template:
    spec:
      containers:
      - name: container1
        env:
{{- include "env.mysql" . | indent 10 }}
          - name: OTHER_ENVIRONMENT_VARIABLES
            value: are okay too

Having defined the template once, you can include it as many times as you need to.

  • Related