Helm's v3 Example Doesn't Show Multi-line Properties. Get YAML to JSON parse error

12/9/2021

In Helm's v3 documentation: Accessing Files Inside Templates, the author gives an example of 3 properties (toml) files; where each file has only one key/value pair.

The configmap.yaml looks like this. I'm only adding one config.toml for simplicity.

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-config
data:
  {{- $files := .Files }}
  {{- range tuple "config.toml" }}
  {{ . }}: |-
    {{ $files.Get . }}
  {{- end }}

This works fine, until I add a second line to the config.toml file.

config.toml

replicaCount=1
foo=bar

Then I get an Error: INSTALLATION FAILED: YAML parse error on deploy/templates/configmap.yaml: error converting YAML to JSON: yaml: line 9: could not find expected ':'

Any thoughts will be appreciated. Thanks

-- paiego
helm3
kubernetes
kubernetes-helm

1 Answer

12/10/2021

Helm will read in that file, but it is (for good or bad) a text templating engine. It does not understand that you are trying to compose a YAML file and thus it will not help you. That's actually why you will see so many, many templates in the wild with {{ .thing | indent 8 }} or {{ .otherThing | toYaml }} -- because you need to help Helm know in what context it is emitting the text

Thus, in your specific case, you'll want the indent filter with a value of 4 because your current template has two spaces for the key indent level, and two more spaces for the value block scalar

data:
  {{- $files := .Files }}
  {{- range tuple "config.toml" }}
  {{ . }}: |-
{{ $files.Get . | indent 4 }}
{{/* notice this ^^^ template expression is flush left,
because the 'indent' is handling whitespace, not the golang template itself */}}
  {{- end }}

Also, while this is the specific answer to your question, don't overlook the .AsConfig section on that page which seems much more likely to be what you really want to happen, and requires less indent math

-- mdaniel
Source: StackOverflow