With helm template file conditionally set a variables used throughout template file

Viewed 651

I want to conditionally set a 'go' variable at the top of my helm template file then use it later in the template file. Here is what I tried that doesn't work:

At the top of my template file, I do the following:

{{- if eq $.Values.kafka.create true -}}
{{- $kafka_port := 9094 -}}
{{- else -}}
{{- $kafka_port := $.Values.kafka.port -}} 
{{- end }}

But when I attempt to do "helm install" I get a parse error where I use $kafka_port later in the template file. The specific error is:

Error: parse error at (tombolo/templates/tom-node-launch.yaml:89): undefined variable "$kafka_port"

3 Answers

Define the variable in the outer block:

{{- $kafka_port := 9094 -}}
{{- if eq $.Values.kafka.create false -}}
{{- $kafka_port = $.Values.kafka.port -}} 
{{- end }}

Your example is pretty short and may well be ok for your use case.

But as a general rule : when you start writing code in your templates, it could also be an indication that you should write code in the controller part (the go code) :

type KafkaCfg struct {
    port   int
    create bool
}

const kafkaCreationPort = 9094

func (c KafkaCfg) Port() int {
    if c.create {
        return kafkaCreationPort
    }
    return c.port
}


func someWhereElse() {
    var data struct {
        Values struct {
            Kafka KafkaCfg
        }
    }

    data.Values.Kafka.create = true
    helmTemplate.Execute(w, data)
}

// in your template :

{{ .Values.Kafka.Port }} {{ /* <- will call the .Port() method */ }}

https://play.golang.org/p/6pNHY0kcegp

The Go text/template language (as distinct from the Go programming language itself) doesn't have global variables.

The thing you can do is to write a helper template, typically in templates/_helpers.tpl, that generates this fragment:

{{- define "kafka.port" -}}
{{- if .Values.kafka.create -}}
9094
{{- else -}}
{{- .Values.kafka.port -}}
{{- end -}}

This template outputs the port number when called; its single parameter should be the standard top-level Helm object.

- name: KAFKA_PORT
  value: {{ include "kafka.port" . | quote }}

Or, if in a specific context, you happen to need it as a variable, you can include it there (using the Helm include extension to capture the called template's output as a string); but it will be limited to its specific template or file.

{{- $kafkaPort := include "kafka.port" . }}
- name: KAFKA_PORT
  value: {{ quote $kafkaPort }}
- name: KAFKA_BROKER_URL
  value: kafka://{{ include "kafka.name" . }}:{{ $kafkaPort }}
Related