eazary
eazary

Reputation: 159

Use variable to define other variables

I’m trying to defines some variables in order to make my helm chart non-repeatable

I created a helpers file which contains the following section:

{{ $config := .Values.service }}
{{- range .Values.services }}
{{ $config.$serviceName }}
{{- define "{{ $serviceName }}.selectorLabels" -}}
app.kubernetes.io/name: {{ .name }}
app.kubernetes.io/instance: {{ .instance }}
{{- end -}}
{{- end -}}

values.yaml:

services:
- service1
- service2
- service3

service:
- service1:
    name: service1

- service2:
    name: service2
    
- service3:
    name: service3

but it keeps prompting an error for bad character U+0024 ‘$’

Do you know how can I define a variable by other variable?

Upvotes: 1

Views: 3264

Answers (1)

David Maze
David Maze

Reputation: 159830

Neither the Go text/template language, the Sprig extensions, nor Helm's local extensions have a way to define a template with a dynamic name. The name in a define call must be a fixed string. The text/template documentation notes (under "Nested template definitions"):

Template definitions must appear at the top level of the template.... The define action names the template being created by providing a string constant.

However, templates take a (single) parameter. Instead of trying to define a separate template for each dynamically-specified value, you could define a single template that produces this content, and then call it with the dynamic settings.

{{- define "selectorLabels" -}}{{/* <-- fixed name */-}}
{{/* .name is relative to the template parameter . */-}}
app.kubernetes.io/name: {{ .name }}
app.kubernetes.io/instance: {{ .instance }}
{{- end -}}

{{- range .Values.services }}
{{-/* . is one item from the services list */}}
{{ include "selectorLabels" . }}
{{- end -}}

You may find a simpler Helm values structure easier to work with as well. If you decompose .Values.service, it is a list, where each list is a single-item dictionary, where the key comes from a separate list. You might structure this as a single flat list of settings dictionaries, embedding the item name as a name: value within the structure (like for example the containers: list in a pod spec).

services:
  - name: service1
    instance: foo
  - name: service2
    instance: bar
  - name: service3
    instance: baz

Upvotes: 2

Related Questions