Search code examples
yamlkubernetes-helmconfigmap

Helm create configmap with different names from values file


I'm trying to create configmaps with different names based on the multiPod variable in the values file. If the multiPod variable is set to True, then helm should create 3 CM based on the region and 1 CM based on the key like cm-storage or cm-compute. Please help me in achieving this use case. TIA

configMap.yaml

{{- range $keys, $values := $.Values.topicsToRead }}

{{- if $values.multiPod }}
{{- range $values.region }}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-{{ . }}
data:
  features.toml: |
    [features]
    x_enabled = false
{{- end -}}
{{- end }}
{{- end }}

Values.yaml

topicsToRead:
  compute:
    multiPod: true
    region:
      - region815
      - region816
      - region817
  storage:
    multiPod: false
    region:
      - region715
      - region716
      - region717

Output:

❯ helm template -s templates/configmap.yaml .
---
# Source: helm-chart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-region815
data:
  features.toml: |
    [features]
    x_enabled = false
---
# Source: helm-chart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-region816
data:
  features.toml: |
    [features]
    x_enabled = false
---
# Source: helm-chart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-region817
data:
  features.toml: |
    [features]
    x_enabled = false

Output I want:

❯ helm template -s templates/configmap.yaml .
---
# Source: helm-chart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-region815
data:
  features.toml: |
    [features]
    x_enabled = false
---
# Source: helm-chart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-region816
data:
  features.toml: |
    [features]
    x_enabled = false
---
# Source: helm-chart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-region817
data:
  features.toml: |
    [features]
    x_enabled = false
---
# Source: helm-chart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-storage
data:
  features.toml: |
    [features]
    x_enabled = false

Solution

  • I think you have to break this up into multiple templates. You can write a template that produces the ConfigMap content:

    {{- /* Produce a ConfigMap.  Pass a dictionary with a key "name" as the
           parameter. */ -}}
    {{- define "configmap" -}}
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: {{ .name }}
    data:
      features.toml: |
        [features]
        x_enabled = false
    {{ end -}}
    

    Once you have this, then you can call it from the outer template. Since you have it as a separate helper template, you can invoke it without copying the template content even if multiPod is false.

    {{- range $k, $v := $.Values.topicsToRead }}
      {{- if $v.multiPod }}
        {{- range $v.region }}
          {{- include "configmap" (dict "name" (printf "cm-%s" .)) -}}
        {{- end -}}
      {{- else -))
        {{- include "configmap" (dict "name" (printf "cm-%s" $k)) -}}
      {{- end -}}
    {{- end -}}
    

    (I've indented this for readability, but also made sure absolutely every template element has - whitespace-control markers. I've used $v as the loop variable name mostly to distinguish from the standard Helm .Values.)

    The one other trick I've used here is the dict. A Helm template only takes a single parameter. I'm guessing you're not generating the same fixed content for every single ConfigMap, so what I've done here is to pass a dictionary as the parameter. I compute its name in the outer template, and then can refer to it as .name (the name field on the parameter variable .) in the inner template. You can extend this to add more "parameters" by including them in the dict parameter.