helmfile
helmfile copied to clipboard
Templating complex values.yaml files
Consider the following values.yaml
file. This is an excerpt from the default values file for the prometheus helm chart:
## ConfigMap override where fullname is {{.Release.Name}}-{{.Values.server.configMapOverrideName}}
## Defining configMapOverrideName will cause templates/server-configmap.yaml
## to NOT generate a ConfigMap resource
##
configMapOverrideName: ""
When we're attempting to use helmfile to template into this values.yaml.gotpl
file, we are seeing errors. Obviously it is picking up on {{
and seeing it as a template. We can accept this for comments since they can simply be deleted, however the same thing is happening for nested values that are not in comments.
## alertmanager ConfigMap entries
##
alertmanagerFiles:
alertmanager.yml:
global:
slack_api_url: 'https://slack.com'
receivers:
- name: default-receiver
pagerduty_configs:
- service_key: key
slack_configs:
- channel: '{{ .CommonAnnotations.channel }}'
send_resolved: true
title: '{{ template "slack.default.title" . }}'
title_link: '{{ template "slack.default.titlelink" . }}'
pretext: '{{ .CommonAnnotations.summary }}'
text: |-
{{ range .Alerts }}
*Alert:* {{ .Annotations.summary }} - `{{ .Labels.severity }}`
*Description:* {{ .Annotations.description }}
*Details:*
{{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}`
{{ end }}
{{ end }}
To be completely honest, I don't really know what the answer to this question is. It is understandable that helmfile
is detecting these interpolation tokens - however it introduces a lot of escaping and complexity. Given that prometheus is such a widely used chart, I felt it was worth raising to start a discussion.
@ChrisCooney Thanks for trying helmfile and bringing this up! I feel frustrated to this problem as well. Perhaps you may be interested in #658 for a possible longer-term solution.
Have you tried making your all or part(s) of your values.yaml non-template file(Omit .tpl
), so that it isn't rendered as a go template? Or escaping expressions?
{{` {{ .Whatever }} `}}
If you've already tried that, and you still wanted to have a single file that has nice comments containing example template expressions and alertmanager configs - yeah we don't currently have an elegant way .
Since #658 I've considered another delimiters for helmfile templates, like (( ))
, [[ ]]
, {{{ }}}
but each of them seems to have its own pros and cos.
That's why I started to think that we eventually need a completely different "language" that doesn't conflict with go templates. There's a bunch of "embedded" languages used for generating dynamic configs - Skylark(See kubetest), Rego(See conftest), Lua(Helm v3, gofish), ECMAScript(jkcfg/jk), and so on.
One of helmfile ways is that being consistent with helm. Fortunately helm v3 is introducing Lua support for chart libraries and hooks. So add Lua as an another language to describe dynamic helmfile values.yaml files?
I'm okay with Lua but not sure if everyone is. WDYT?
Can I drop the name of k14s/ytt
as an alternative templating option? It's been getting a lot of popularity lately. Just putting it out there for consideration 👍
@aegershman Yeah I'm eager to add various templating options. The only consideration needed here is how to implement it without bloating the helmfile codebase 😄
Perhaps someone could propose a pluggable template engine system for helmfile so that helmfile is able to use any template engine without bloating code and sacrificing binary size.
I'd say only go template and Lua can be the first-class citizens to make helmfile friendly for helm users.
tried to configure prometheus alertmanager templates and faced with this issue. any news regarding this issue ? seems like the problem is still actual...
@StepanKuksenko Hey! Sorry but could you share what you've tried? This is already "solved" with the below syntax:
{{` {{ .Whatever }} `}}
That's go text/template's native comment sytnax, so that you can literally render {{ .Whatever }}
without evaluating it as a template expression.
Faced same issue with vector helm chart. Mainly this part:
labels:
forwarder: "vector"
file: '{{ file }}'
stream: "{{ stream }}"
source_type: "{{ source_type }}"
k8s_pod_namespace: "{{ kubernetes.pod_namespace }}"
k8s_pod_name: "{{ kubernetes.pod_name }}"
k8s_pod_uid: "{{ kubernetes.pod_uid }}"
k8s_pod_ip: "{{ kubernetes.pod_ip }}"
k8s_pod_ips: "{{ kubernetes.pod_ips }}"
k8s_pod_node_name: "{{ kubernetes.pod_node_name }}"
k8s_app: "{{ kubernetes.pod_labels.app }}"
k8s_kubernetes_io_instance: '{{ kubernetes.pod_labels.app\.kubernetes\.io/instance}}'
k8s_kubernetes_io_component: '{{ kubernetes.pod_labels.app\.kubernetes\.io/component }}'
k8s_kubernetes_io_name: '{{ kubernetes.pod_labels.app\.kubernetes\.io/name }}'
k8s_container_name: "{{ kubernetes.container_name }}"
k8s_container_image: "{{ kubernetes.container_image }}"
Even if i wrap
file: '{{ file }}'
to
file: {{` '{{ file }}' `}}
It still fails trying to treat file as a function:
parse error at (vector-agent/templates/configmap.yaml:13): function "file" not defined
It uses toYaml to generate resulting configmap
Hi! I have the same problem, I'm trying to set a value to an annotations:
annotations:
alb.ingress.kubernetes.io/conditions.any: "{{ .Values.otherServiceName }}"
alb.ingress.kubernetes.io/conditions.any2: "{{` '{{ .Values.otherServiceName }}' `}}"
And it always renders the instruction to me but does not resolve it. Could someone solve?
Thanks
parse error at (vector-agent/templates/configmap.yaml:13): function "file" not defined
@rlex This seems to be coming from your chart, not helmfile, right? Then almost certainly you're misusing the chart. Mind sharing the chart and the offending chart template, so that we can hopefully see what's going on?
Everyone, please share the exact chart, helmfile.yaml, and all the values.yaml files if you need user support!