Merge two Value files in helm
Asked Answered
S

5

8

I'm looking to merge two values files in helm.

secrets.yaml:

oracle_db:
 serviceMonitor:
   endpoints:
     - module: oracledb
       port: http
       scheme: http
       url: "http://user:password@ip:port/xxx" 

I have another values.yaml file which has multiple endpoints. I want to merge both the values files. I'm tried using append function to do that: {{$endpoints := (append .Values.serviceMonitor.endpoints .Values.oracle_db.serviceMonitor.endpoints) }} When I do a dry-run, I see its picking up both the values but won't merge. Any one come across this?

Stacistacia answered 12/1, 2020 at 1:13 Comment(0)
S
4

You can use a python script to merge the values files before passing them. Below is a code snippet of what I am using.

import yaml
from deepmerge import always_merger

fileA = “tmp.yaml"
fileB = “feature.yaml"

with open(fileA,'r+') as f:
   fileAdictionary= yaml.load(f)

with open(fileB,'r+') as f:
   fileBdictionary = yaml.load(f)

result = always_merger.merge(fileAdictionary, fileBdictionary)
with open(‘newFile.yaml’,'w+') as f:
   yaml.dump(result,f)
Seer answered 25/6, 2020 at 19:59 Comment(0)
M
11

In the current Helm version (3) merging values is not supported.

This feature was discussed in this Github issue: Helm should preform deep merge on multiple values files.

One important quote from there

If this is implemented, it should be optional, i. e. the merge mode should be specified as a command-line flag. Anything else would be a breaking change and, I think, in most cases not desirable. The problem is that you would not be able to override defaults for lists.

See: https://github.com/helm/helm/issues/3486#issuecomment-364534501

Mont answered 15/1, 2020 at 16:30 Comment(0)
S
4

You can use a python script to merge the values files before passing them. Below is a code snippet of what I am using.

import yaml
from deepmerge import always_merger

fileA = “tmp.yaml"
fileB = “feature.yaml"

with open(fileA,'r+') as f:
   fileAdictionary= yaml.load(f)

with open(fileB,'r+') as f:
   fileBdictionary = yaml.load(f)

result = always_merger.merge(fileAdictionary, fileBdictionary)
with open(‘newFile.yaml’,'w+') as f:
   yaml.dump(result,f)
Seer answered 25/6, 2020 at 19:59 Comment(0)
N
3

another option:

{{- define "template.valueOrDefault" -}}
{{- $value := dict -}}
{{- range (rest .) -}}
  {{- $value = merge $value . -}}
{{- end -}}
{{- if $value -}}
{{- printf "%s:" (first .) }}
{{- toYaml $value | nindent 2 }}
{{- end }}
{{- end -}}

usage:

 containers:
 - name: db-migrations-job
   {{- include "template.valueOrDefault" (list "resources" .Values.migrationJob.resources .Values.resources) | nindent 8 }}
Nude answered 9/2, 2023 at 9:5 Comment(0)
B
2

Another method is to use yq:

cat base.yaml 
foo: bar
foo2:
  key1: baz
  key2: rar

cat extend.yaml 
foo: none
foo2:
  key1: yes
  key3: no

merge them like this: yq -n 'load("base.yaml") * load("extend.yaml")'

And the result will be:

foo: none
foo2:
  key1: yes
  key2: rar
  key3: no

Note that the order of files is important, as the second argument will extend the first. yq is also handy since it is included in alpine/helm image already.

Broomcorn answered 4/4 at 19:10 Comment(0)
S
1

Here is a simple python script to merge values.yaml files with best effort to preserve comments, formatting, and order of items.

https://github.com/Aref-Riant/yaml-merger-py

usage:

python yaml-merger.py file1.yaml file2.yaml > mergedfile.yaml
Spectrometer answered 24/4, 2023 at 6:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.