Helm - how to call helper functions in a loop?

11/5/2018

I'm trying to define n StatefulSets where n is the number of nodes required, set in values.yaml as nodeCount. I get an error that looks to be scope related, but I can't seem to get the scope sorted out. Am I missing something here?

The relevant content in my StatefulSet .yaml file:

{{ range $k, $v := until ( .Values.nodeCount | int) }}
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: {{ $.Release.Name }}  
  labels:
    app: {{ $.Release.Name }}
    chart: {{ template "myapp-on-kube.chart" . }}  #here's my call to _helpers
    release: {{ $.Release.Name }}
    heritage: {{ $.Release.Service }}

The relevant content in _helpers.tpl:

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "myapp-on-kube.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

The error I get:

Error: render error in "myapp-on-kube/templates/statefulset.yaml": template: myapp-on-kube/templates/_helpers.tpl:31:25: executing "myapp-on-kube.chart" at <.Chart.Name>: can't evaluate field Chart in type int
-- user797963
kubernetes-helm

1 Answer

11/5/2018

Several of the Go templating constructs change the meaning of . to be the thing that's being looped over, and you need to use $ to refer to the initial value. Most of your template correctly refers to e.g. $.Release.Name, but when you invoke the helper template, it's using the current context rather than the root value. Change:

chart: {{ template "myapp-on-kube.chart" $ }}

(Note that the template as you have it will declare several StatefulSets all with the same name, which won't go well. I might create just one StatefulSet with replicas: {{ .Values.nodeCount }}.)

-- David Maze
Source: StackOverflow