Helm use template function inside llops

4/9/2020

I am trying to use the {{ template }} function on my helm chart, but inside a loop the value does error.

First here is my _helpers.tpl:

{{- define "traefik.deployNamespace" -}}
    {{ default "kube-system" .Values.deployNamespace }}
{{- end -}}

I can use that variable with {{ template "treafik.deployNamespace }} on all the templates, expect when inside a loop:

# Iterates on allowed namespaces and creates the roles
{{- if .Values.allowedNamespaces }}
{{- range .Values.allowedNamespaces }}
# Rules for namespace: {{ . }}
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: {{ . }}-traefik-ingress-r
  namespace: {{ . }}
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch

---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: {{ . }}-traefik-ingress-rb
  namespace: {{ . }}
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: {{ . }}-traefik-ingress-r
subjects:
- kind: ServiceAccount
  name: traefik-ingress-sa
  namespace: {{ template "traefik.deployNamespace" . }}
{{- end }}
{{- end }}

I am probably doing the $ctx wrong, but I don't know what I should use in there.

> % helm template .
Error: template: traefik/templates/_helpers.tpl:62:36: executing "traefik.deployNamespace" at <.Values.deployNamespace>: can't evaluate field Values in type strin
-- Alfredo Palhares
kubernetes-helm

1 Answer

4/10/2020

At the bottom of the file you have a couple of uses of the . current-context variable. Inside the context of a {{ range }}...{{ end }} loop, . gets set to the item from the list you're iterating over.

# `.` in all three of these is the same thing (a string)
name: {{ . }}-traefik-ingress-rb
namespace: {{ . }}
namespace: {{ template "traefik.deployNamespace" . }}

Templates generally expect to get the top-level Helm environment object as their parameter (a dictionary-type object with "Charts", "Values", and so on). You need to save it away outside your loop in a variable so you can get access to it.

{{- $top := . }}
{{- range .Values.allowedNamespaces }}
...
  namespace: {{ template "traefik.deployNamespace" $top }}
...
{{- end }}
-- David Maze
Source: StackOverflow