Helm Charts with multiple lists in multiple values files
Asked Answered
B

3

22

I have a values.yaml that has the following:

abc:
  env:
  - name: name01
    value: value01
  - name: name02
    value: value02

and I have another values file values-dev.yaml that I add when installing using -f and it has:

abc:
  env:
  - name: name03
    value: value03

and using range I list them in my template. My hope was that the list would become like this after both files are applied:

abc:
  env:
  - name: name01
    value: value01
  - name: name02
    value: value02
  - name: name03
    value: value03

but the values-dev.yaml values will override the one in the values.yaml and it becomes:

abc:
  env:
  - name: name03
    value: value03

How can I achieve merging these 2 lists with the same field names from different values files?

Bedim answered 18/12, 2019 at 14:44 Comment(1)
Does this thread clarify a bit the usage of multiple values files https://mcmap.net/q/210107/-can-i-have-multiple-values-yaml-files-for-helm ? Did you try to pass those values files in a different order ? In this case you'll probably get final result containing only name01 and name02. It looks like currently there is no way to pass multiple value files so that everything is merged rather than overridden.Casern
G
18

Short answer is, you can not merge lists.

In your case abc.env is the key and the value is a list. Let me re-write your first values file in an equivalent notation and it will be more clear:

abc:
  env: [{name: name01, value: value01}, {name: name02, value: value02}]

So Helm is doing what is expected, overriding the key abc.env with the last provided one.

Solution is re-structuring your values files, like this:

abc:
  env:
    name01: value01
    name02: value02

This way, you can merge and override your values files as desired. This way, it's also much easy to override a single value with command line flag, for example:

--set abc.env.name01=different

With some Helm magic, it's easy to pass those values as environment variables to your pods:

...
  containers:
  - name: abc
    image: abc
    env:
    {{- range $key, $value := .Values.abc.env }}
    - name: {{ $key }}
      value: {{ $value | quote }}
    {{- end }}  
Gisela answered 20/12, 2019 at 19:18 Comment(0)
F
1

This might no always the behavior you want but you can concat two or more lists in helm without any complicated templating. Just use the concat function from lists:

apiVersion: v1
kind: Pod
metadata:
  name: wget
  labels:
    app.kubernetes.io/name: wget
    app.kubernetes.io/instance: wget
    app.kubernetes.io/managed-by: Helm
spec:
  containers:
    - name: wget
      image: busybox
      command: ['sleep']
      args: ['7d']
   volumes:
     {{- toYaml (concat .Values.volumes .Values.defautVolumes) | nindent 4 }}

This adds the two lists volumes and defautVolumes. Empty lists also work.

NOTE: This does not meagre the disks. It produces duplicates if both lists have the same values. You can not use this to override a value from one list by another.

Frilling answered 4/1, 2024 at 16:15 Comment(0)
S
0

You can to "merge" values manually if they have a standard unique key like name in env var definition:

First build dict with env values, if env name is encountered multiple times it will overwrite the previous value

{{- $envVars := dict -}}
{{- range .Values.abc.env -}}
{{- $envVars := set $envVars .name . -}}
{{- end -}}

Then add it to the template

...
  containers:
  - name: abc
    image: abc
    env:
    {{- range $envVars -}}
    - {{ toYaml . | nindent 6 | trim }}
    {{- end -}}

You may need to change nindent value to match your template format.

Syman answered 19/7, 2024 at 23:36 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.