Helm merge and dict directives?

4/10/2020

I one of Helm chart examples I come across the following lines:

{{- define "common.deployment" -}}
{{- $common := dict "Values" .Values.common -}} 
{{- $noCommon := omit .Values "common" -}} 
{{- $overrides := dict "Values" $noCommon -}} 
{{- $noValues := omit . "Values" -}} 
{{- with merge $noValues $overrides $common -}}

But I can't find in helm docs information about omit, merge and dict directives.

-- ogbofjnr
kubernetes-helm
yaml

2 Answers

4/10/2020

These template functions are actually from an underlying package sprig that helm uses.


Creating dictionaries is done by calling the dict function and passing it a list of pairs.

The following creates a dictionary with three items:

$myDict := dict "name1" "value1" "name2" "value2" "name3" "value 3"

Merge two or more dictionaries into one, giving precedence to the dest dictionary:

$newdict := merge $dest $source1 $source2

This is a deep merge operation but not a deep copy operation. Nested objects that are merged are the same instance on both dicts. If you want a deep copy along with the merge than use the deepCopy function along with merging. For example,

deepCopy $source | merge $dest

mustMerge will return an error in case of an unsuccessful merge.


The omit function is similar to pick, except it returns a new dict with all the keys that do not match the given keys.

$new := omit $myDict "name1" "name3"
-- Kamol Hasan
Source: StackOverflow

4/10/2020

They're part of a template library called Sprig, and more specifically its functions for working with dictionaries.

Using constructs like this it's possible to run templates with what looks like alternate values objects, constructing them from other parts of the original values. In your example, say the next line (inside the {{ with }}...{{ end }}) block was just {{ toYaml .Values }}. If the original values.yaml file contains something like

common:
  a: "one"
  b: "two"
a: "three"
c: "four"

the code you show will in effect "promote" the common content to the top level, but making actual top-level values override it, and you will get out

a: "three"
b: "two"
c: "four"

($common is a dictionary containing the contents of .Values.common, under a top-level "Values" key. $noCommon is a dictionary containing all of .Values except the common key, still under "Values", and $noValues is a dictionary containing "Chart", "Release", and the other top-level values. These all get merged together into a single dictionary with $noCommon overriding $common.)

-- David Maze
Source: StackOverflow