arash moeen
arash moeen

Reputation: 4693

Helm Charts with multiple lists in multiple values files

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?

Upvotes: 23

Views: 24778

Answers (3)

Alexei Tenitski
Alexei Tenitski

Reputation: 9360

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.

Upvotes: 0

hegerdes
hegerdes

Reputation: 98

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.

Upvotes: 1

r a f t
r a f t

Reputation: 441

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 }}  

Upvotes: 18

Related Questions