1
votes

I'm new to helm and I want to be able to write gitlab project variables to files using config maps and shared environment variables.

I have a set of environment variables defined as gitlab project variables (the gitlab runner exposes them as environment variables) for each environment (where <ENV> is DEV/TEST/PROD for the sake of brevity):

MYSQL_USER_<ENV> = "user"
MYSQL_PASSWORD_<ENV> = "pass"

In the helm chart every environment has a map of its variables. For example, values.<ENV>.yaml contains:

envVars:
  MYSQL_USER: $MYSQL_USER_<ENV>
  MYSQL_PASSWORD: $MYSQL_PASSWORD_<ENV>

values.yaml contains a Ruby file which will consume those variables:

files:
  config.rb: |
    mysql['username'] = ENV["MYSQL_USER"]
    mysql['password'] = ENV["MYSQL_PASSWORD"]

configmap.env.yaml defines:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "mychart.fullname" . }}-config-env
data:
{{- range $config_key, $config_value := .Values.envVars }}
  {{ $config_key }}: {{ $config_value | quote | nindent 4 }}
{{- end }}

configmap.files.yaml defines:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ include "mychart.fullname" . }}-config-volume
data: 
{{- range $file_path, $file_content := .Values.files }}
  {{ $file_path }}: |
{{ $file_content | indent 4 -}}
{{- end }}

Finally, the deployment of the config map (only the config map part is shown here and I'm not using secrets here because this question is long enough as it is):

      volumes:
        - name: {{ include "mychart.fullname" . }}-config-volume
          configMap:
            name: {{ include "mychart.fullname" . }}-config-volume
      containers:
        - name: {{ .Chart.Name }}
          volumeMounts:
          - name: {{ include "mychart.fullname" . }}-config-volume
            mountPath: /etc/my-config-dir
          envFrom: 
            - configMapRef:
                name: {{ include "mychart.fullname" . }}-config-env

So, in one sentence the workflow should be: MYSQL_USER/PASSWORD_<ENV> saved into MYSQL_USER/PASSWORD, which are then written to /etc/my-config-dir/config.rb

I can't seem to make the environment variables of values.yaml (MYSQL_USER, MYSQL_PASSWORD) get the value of the project variables (MYSQL_USER_<ENV>, MYSQL_PASSWORD_<ENV>). I use helm 3, but {{ env "MYSQL_USER_<ENV>" }} fails. I could use string interpolation with the environment variable's name it the Ruby file, but then I would have to know what environment variables should be created for every container.

I'm trying to avoid having multiple --set arguments. Also I'm not sure how envsubst can be used here...

Any help will be greatly appreciated, thanks!

1
I guess I'll have to write the environment variables to a file and export them... When I get to this I'll create an answer. - towel
You might find it more convenient to write out the variables as a JSON file. Helm will accept a JSON-format values file in a helm install -f option. (...because valid JSON is valid YAML.) - David Maze
@DavidMaze I agree, but unfortunately I have to use gitlab project variables. - towel

1 Answers

2
votes

So eventually I used envsubst:

  script:
    - VALUES_FILE=values.${ENV}.yaml
    - envsubst < ${VALUES_FILE}.env > ${VALUES_FILE}
    - helm upgrade ... -f ${VALUES_FILE}