Helm & variable scopes

I'm working on a helm chart that dynamically issues entire PKIs using certmanager.

A pki is fairly simply: At the top you've a root CA which is self-signed, the root issues intermediates or certificates directly, depending on your needs and expected use case.

The requirement is simple: Create once a root issuer and then an issuer per CA.

{{- range $instance, $settings := include "pki.instances" $ | fromYaml -}}
{{- $rootIssuerCreated := false -}}
{{- if eq $settings.type "certmanager" }}
{{- if eq $rootIssuerCreated false }}
{{- $rootIssuerCreated := true }}
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: {{ include "fullname" $ }}-pkihelper-rootissuer
  namespace: {{ $.Release.Namespace }}
  labels:
    {{- include "labels" $ | nindent 4 }}
spec:
  selfSigned: {}
{{- end }}
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: {{ include "fullname" $ }}-pki-{{ $instance }}
  namespace: {{ $.Release.Namespace }}
  labels:
    {{- include "labels" $ | nindent 4 }}
spec:
  ca:
    secretName: {{ include "fullname" $ }}-pki-{{ $instance }}
{{- end }}
{{- end }}

first approach

Unfortunately, this code has a bug - it creates the variable $rootIssuerCreated inside the range and helm scope means that the variable is then inside the loop scope.

The solution is fairly simple, just declare the variable outside the loop. It's just not obvious, as the scope can easily be missed, compared to common programming languages.

The fix is here:

{{- $rootIssuerCreated := false -}}
{{- range $instance, $settings := include "pki.instances" $ | fromYaml -}}
{{- if eq $settings.type "certmanager" }}
{{- if eq $rootIssuerCreated false }}
{{- $rootIssuerCreated := true }}

fixed version

Just swap line 1 & 2 - happy.