YAML
Example https://github.com/buttahtoast/helmize/tree/main/examples/example-yaml
Multi YAML
Helmize supports multi YAML files (Multiple YAMLs in one file separeted by - - -
). The implementation is relativ primitive: If a file contains it’s split into multiple sub files, which then are treated as seperated files for further processing.
Limitation
The fromYaml
function can not parse multiple yaml files, but is aware of the delimiter. If you have the following example:
{{- define "sample.data" -}}
---
First: YAML
---
Second: YAML
{{- end -}}
{{- $t := (fromYaml (include "sample.data" $)) -}}
{{- toYaml $t -}}
You will get the following output:
$ helm template .
---
# Source: test/templates/test.yaml
First: YAML
Meaning the function only parses the first YAML found.
Workaround
This is simplified version of how helmize parses multi YAML files. In the first step the entire file is templated (So it’s also possible to generate more files via templating within a file). The input is still of type string. No the entire content is split by ---
resulting in sub files. In the iteration it’s checked if there is any content (when two ---
come after each other the splitList
function will create a entry with " "
. Therefor we check if its empy without spaces). Then the content is loaded to yaml (and verified if the yaml is valid).
NOTE: The split looks for \n---
. So make sure YAML indicators come after a linebreak.
{{- define "sample.data" -}}
---
First: {{ $.Release.Name }}
---
Second: YAML
---
---
third: YAML
{{- end -}}
{{- $t := (tpl (include "sample.data" $) $) -}}
{{- $f := splitList "---" $t | compact -}}
{{- range $i, $c := $f -}}
{{- if ($c | nospace | trimAll "\n") }}
{{ $i }}: {{- toYaml (fromYaml ($c)) | nindent 0 }}
{{- end }}
{{- end -}}
The result for the above template is:
$ helm template .
---
# Source: test/templates/test.yaml
0:
First: release-name
1:
Second: YAML
3:
third: YAML
Understanding this might help working with multi YAML files.
Hints
Here are some hints regarding Multi YAML files
Nested YAML Data
You can still use multi line YAML’s, our implementation should not interefer with them:
structure/resources/multi-line.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
entrypoint.sh: |-
#!/bin/bash
echo "Do this"
game.properties: |
---
enemy:
types:
- alien
- monsters
player:
maximumLives:5
Wrong Templating
There might be cases where to templating does not validate correctly and therefor you might have unexpected output. Take for example this template:
structure/resources/wrong-template.yaml
{{- range $f, $d := (fromYaml (include "data" $)).data -}}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap-{{ $f }}
data:
field: {{ $d }}
{{- end -}}
{{- define "data" -}}
data:
name_1: val_1
name_2: val_2
name_3: val_3
{{- end -}}
But as output we only get:
# Source: multi-yaml/templates/deploy.yaml
# File: [configmap-configmap-name_3.yaml]
# Checksum 7cc3553b2b3ec675cbdad142ce0293cc4f523d3d5aed8bd46d42451f82c3d7bc
apiVersion: v1
data:
field: val_3
kind: ConfigMap
metadata:
name: configmap-name_3
The other two configmaps are missing. With the summary we can see what happened:
Under partial_files
we should see 3 entries. Instead it’s a single entry. That’s because the split does not match \n---
because the template does not print a new line after each iteration. Let’s fix that in the template (Note the missing -
in the closing brackets):
structure/resources/wrong-template.yaml
{{- range $f, $d := (fromYaml (include "data" $)).data }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap-{{ $f }}
data:
field: {{ $d }}
{{- end }}
Now if we look again at the summary, we see three entries and all three configmaps are printed: