Helm Charts with multiple lists in multiple values files

12/18/2019

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?

-- arash moeen
kubernetes
kubernetes-helm

2 Answers

12/18/2019

I personally don't prefer multiple env value files. The best to do is using this approach.

Keep a single values file having something like this.

mongodb_ip:
  prod: 10.0.2.201
  staging: 10.0.2.202
  test: 10.0.2.203
  dev: 10.0.2.204

And inside your config file or deployment file you can call the values using

data:
  debug: 'false'
  mongodb_ip: '{{ pluck .Values.envName .Values.mongodb_ip | first }}'

And before helm install or helm upgrade run this command on your CI/CD pipeline, but make sure you have yq tool installed to do the thing. Or you can use any tool to do the same.

yq w -i values.yaml envName dev

This whole process replaces my config file with mongodb ip of 10.0.2.204 as I gave dev in yq tool.

This is sample of how we can have single values file, and configure it to multiple regions or environments based on your need, instead of multiple value files.

On the other hand you can also use --values or -f flag like you said based on your usage. And try something like this. This is when you want to use multiple files with multiple clients or something like that.

helm install ./path --values ./generic-values.yaml --values ./dev-values.yaml

Hope it is helpful.

-- BinaryMonster
Source: StackOverflow

12/20/2019

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 }}  
-- r a f t
Source: StackOverflow