Escaping helm yml for deployment

6/24/2019

I am trying to figure out how to escape these pieces of a yml file in order to use with helm.

            - name: SYSLOG_TAG
              value: '{{ index .Container.Config.Labels "io.kubernetes.pod.namespace" }}[{{ index .Container.Config.Labels "io.kubernetes.pod.name" }}]'
            - name: SYSLOG_HOSTNAME
              value: '{{ index .Container.Config.Labels "io.kubernetes.container.name" }}'

The yml file is a DaemonSet for sending logs to papertrail with instructions here for a standard kubernetes manual deployment https://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-kubernetes/ . Here is a link to the full yml file https://help.papertrailapp.com/assets/files/papertrail-logspout-daemonset.yml .

I found some answers on how to escape the curly braces and quotes, but still can't seem to get it to work. It would be easiest if there was some way to just get helm to not evaluate each entire value.

The last I tried was this, but still results in an error.

              value: ''"{{" index .Container.Config.Labels \"io.kubernetes.pod.namespace\" "}}"["{{" index .Container.Config.Labels \"io.kubernetes.pod.name\" "}}"]''
            - name: SYSLOG_HOSTNAME
              value: ''"{{" index .Container.Config.Labels \"io.kubernetes.container.name\" "}}"''

This is the error:

Error: UPGRADE FAILED: YAML parse error on templates/papertrail-logspout-daemonset.yml: error converting YAML to JSON: yaml: line 21: did not find expected key

I can hardcode values for both of these and it works fine. I don't quite understand how these env variables work, but what happens is that logs are sent to papertrail for each pod in a node with the labels from each of those pods. Namespace, pod name, and container name.

          env:
            - name: ROUTE_URIS
              value: "{{ .Values.backend.log.destination }}"
{{ .Files.Get "files/syslog_vars.yaml" | indent 13 }}
-- Corey
kubernetes
kubernetes-helm

1 Answer

6/25/2019

Two sensible approaches come to mind.

One is to define a template that expands to the string {{, at which point you can use that in your variable expansion. You don't need to specially escape }}.

{{- define "cc" }}{{ printf "{{" }}{{ end -}}
- name: SYSLOG_HOSTNAME
  value: '{{cc}} index .Container.Config.Labels "io.kubernetes.container.name" }}'

A second approach, longer-winded but with less escaping, is to create an external file that has these environment variable fragments.

# I am files/syslog_vars.yaml
- name: SYSLOG_HOSTNAME
  value: '{{ index .Container.Config.Labels "io.kubernetes.container.name" }}'

Then you can include the file. This doesn't apply any templating in the file, it just reads it as literal text.

env:
{{ .Files.Get "files/syslog_vars.yaml" | indent 2 }}

The important point with this last technique, and the problem you're encountering in the question, is that Helm reads an arbitrary file, expands all of the templating, and then tries to interpret the resulting text as YAML. The indent 2 part of this needs to match whatever the rest of your env: block has; if this is deep inside a deployment spec it might need to be 8 or 10 spaces. helm template will render a chart to text without trying to do additional processing, which is really helpful for debugging.

-- David Maze
Source: StackOverflow