kuberneteskubernetes-helm

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


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


Solution

  • 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