Is there a way to validate/parse a YAML file with go-template variables in it?

Viewed 3307

I have a "YAML" file. And I want to validate it before I render the go-template variables in it. For example:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ .Values.favorite.drink | default "tea" | quote }}
  food: {{ .Values.favorite.food | upper | quote }}

The typical YAML parser doesn't work here, as it will parse { as the start of a map.

err := yaml.Unmarshal(data, &Content)
// Failed to parse the provided YAML: yaml: line 4: did not find expected key

I wonder if there is any package that can help me do this? I've searched online for a while but have no luck. Thanks for any help!

2 Answers

It's not just the YAML parser complaining: that actually is invalid YAML (because the {...} is inline mapping syntax). That looks like it comes from the Kubernetes Helm deployment tool, and some routine-but-interesting uses really actually require rendering the YAML.

In practice what you probably want is to use the helm template command to render a chart to multi-document YAML, and then run a YAML validator on that. It doesn't seem to be documented, but Helm version 3 will actually do this validation on its own (Helm 2 doesn't) so if your chart produces invalid YAML you'll get an error at that point.

The way Helm works, it interprets this "YAML" file as a plain text file and applies Go text/template templating to it, and then reads it back as YAML. To some extent you could make this valid YAML by quoting strings yourself:

name: "{{ .Release.Name }}-configmap"

But there's some fairly common constructs where this will actually break the generated YAML. For example, the helm create template generates

{{/* _helpers.tpl */}}
{{- define "<CHARTNAME>.labels" -}}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
{{- end -}}
metadata:
  name: {{ include "<CHARTNAME>.fullname" . }}
  labels:
    {{- include "<CHARTNAME>.labels" . | nindent 4 }}

and no amount of quoting will make this valid YAML. It's very possible to put something into the "labels" helper template that's not valid in a YAML mapping context and you want to catch that in your validation stage.

No, this is not possible. Evaluate the template first.

Related