helm icon indicating copy to clipboard operation
helm copied to clipboard

Helm template generates empty template with braces

Open malcolm061990 opened this issue 2 years ago • 5 comments

Output of helm version: version.BuildInfo{Version:"v3.8.0", GitCommit:"d14138609b01886f544b2025f5000351c9eb092e", GitTreeState:"clean", GoVersion:"go1.17.6"}

Output of kubectl version: Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.2", GitCommit:"8b5a19147530eaac9476b0ab82980b4088bbc1b2", GitTreeState:"clean", BuildDate:"2021-09-15T21:31:32Z", GoVersion:"go1.16.8", Compiler:"gc", Platform:"darwin/amd64"}

Hi. I have:

# templates/configmap.yaml
{{- include "common-chartlib.configmap" (list . "backend.configmap") -}}
{{- define "backend.configmap" -}}
{{- end -}}

# common-chartlib that is used above
{{- define "common-chartlib.configmap.tpl" -}}
{{- if .Values.configMapDef}}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Values.configMapDef.name }}
data:
  {{- range $key, $val := .Values.configMapDef.data}}
  {{ $key }}: {{ $val | quote }}
  {{- end }}
{{- end}}
{{- end}}
{{- define "common-chartlib.configmap" -}}
{{- include "common-chartlib.util.merge" (append . "common-chartlib.configmap.tpl") -}}
{{- end -}}

When I launch the template command it generates "almost empty" template with only braces that can't be used in kubernetes but I don't need any output here:

helm template . --name-template backend -s templates/configmap.yaml -f dev/common.yaml -f dev/redis.yaml # launch this
---
# Source: backend/templates/configmap.yaml
{}  # this line is the issue

How can I make the output empty? I can't just remove backend/templates/configmap.yaml because this file is used in other values.yaml files

malcolm061990 avatar Sep 09 '22 15:09 malcolm061990

Want to link the chart that you're working on? There's not enough here for me to duplicate it and I don't see anything obvious.

joejulian avatar Sep 13 '22 23:09 joejulian

@joejulian Sorry, its our internal chart. Ok, let me clarify. We have this files in chart:

# templates/configmap.yaml file
{{- include "common-chartlib.configmap" (list . "backend.configmap") -}}
{{- define "backend.configmap" -}}
{{- end -}}

# Chart.yaml
apiVersion: v2
name: app
description: Helm chart for app
type: application
version: "0.0.10"
appVersion: "0.0.10"

dependencies:
- name: common-chartlib
  version: 0.1.0
  repository: file://../../../common-chartlib

# common-chartlib/templates/_configmap.yaml
{{- define "common-chartlib.configmap.tpl" -}}
{{- if .Values.configMapDef}}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Values.configMapDef.name }}
data:
  {{- range $key, $val := .Values.configMapDef.data}}
  {{ $key }}: {{ $val | quote }}
  {{- end }}
{{- end}}
{{- end}}
{{- define "common-chartlib.configmap" -}}
{{- include "common-chartlib.util.merge" (append . "common-chartlib.configmap.tpl") -}}
{{- end -}}

# values-2.yaml
configMapDef:
  name: configmap
  data:
    VAR1: val1
    VAR2: val2

When I launch helm template cli command it shows the output with "{}" that can't be used in helm or kubectl commands to deploy it:

# default values.yaml file doesn't contain configmap config. It generates "{}" output, not expected
helm template . --name-template test -s templates/configmap.yaml 
---
# Source: templates/configmap.yaml
{}

# values-2.yaml contains configmap config. Works as expected
helm template . --name-template test -s templates/configmap.yaml -f values-2.yaml 
---
# Source: templates/configmap.yaml
apiVersion: v1
data:
  VAR1: val1
  VAR2: val2
kind: ConfigMap
metadata:
  name: configmap

The reason why I have templates/configmap.yaml file is that using default value.yaml I don't need manifest output (like "{}" now) and using values-2.yaml I need configmap manifest output. How can I remove the "{}" output?

malcolm061990 avatar Sep 14 '22 08:09 malcolm061990

I do understand the question. Taking what you've given me, I still cannot duplicate this issue.

Error: template: app/templates/configmap.yaml:1:4: executing "app/templates/configmap.yaml" at <include "common-chartlib.configmap" (list . "backend.configmap")>: error calling include: template: app/charts/common-chartlib/templates/_configmap.yaml:14:4: executing "common-chartlib.configmap" at <include "common-chartlib.util.merge" (append . "common-chartlib.configmap.tpl")>: error calling include: template: no template "common-chartlib.util.merge" associated with template "gotpl"

I'm happy to help you debug your chart, but you'll have to give me something I can reproduce.

joejulian avatar Sep 14 '22 18:09 joejulian

@joejulian Thanks for your support. Steps:

  • create chart test:
# templates/configmap.yaml
{{- include "common-chartlib.configmap" (list . "backend.configmap") -}}
{{- define "backend.configmap" -}}
{{- end -}}

# Chart.yaml
apiVersion: v2
name: test
description: Helm chart for tesst
type: application
version: "0.0.10"
appVersion: "3.34.1"

dependencies:
- name: common-chartlib
  version: 0.1.0
  repository: file://../common-chartlib

# values.yaml
fullnameOverride: test1

# values-2.yaml
fullnameOverride: test2

configMapDef:
  name: configmap
  data:
    VAR1: val1
    VAR2: val2
  • create common-chartlib dependency chart on the same directory level with test chart:
# Chart.yaml
apiVersion: v2
name: common-chartlib
description: Helm chart librabry for helm packages

type: library
version: 0.1.0
appVersion: "0.1.0"

# templates/_configmap.yaml
{{- define "common-chartlib.configmap.tpl" -}}
{{- if .Values.configMapDef}}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Values.configMapDef.name }}
data:
  {{- range $key, $val := .Values.configMapDef.data}}
  {{ $key }}: {{ $val | quote }}
  {{- end }}
{{- end}}
{{- end}}
{{- define "common-chartlib.configmap" -}}
{{- include "common-chartlib.util.merge" (append . "common-chartlib.configmap.tpl") -}}
{{- end -}}

# templates/_helpers.tpl
{{/*
Expand the name of the chart.
*/}}
{{- define "common-chartlib.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "common-chartlib.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

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

{{/*
Common labels
*/}}
{{- define "common-chartlib.labels" -}}
helm.sh/chart: {{ include "common-chartlib.chart" . }}
{{ include "common-chartlib.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "common-chartlib.selectorLabels" -}}
app.kubernetes.io/name: {{ include "common-chartlib.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "common-chartlib.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "common-chartlib.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

# templates/_util.yaml
{{- define "common-chartlib.util.merge" -}}
{{- $top := first . -}}
{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}}
{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}}
{{- toYaml (merge $overrides $tpl) -}}
{{- end -}}
  • check the directory structure:
tree test/ common-chartlib/
test/
├── Chart.yaml
├── templates
│   └── configmap.yaml
├── values-2.yaml
└── values.yaml
common-chartlib/
├── Chart.yaml
└── templates
    ├── _configmap.yaml
    ├── _helpers.tpl
    └── _util.yaml
  • go to test chart and run:
helm dependency build # build deps

helm template . --name-template test -s templates/configmap.yaml # default values.yaml file doesn't contain configmap config. It generates "{}" output, not expected
---
# Source: test/templates/configmap.yaml
{}

helm template . --name-template test -s templates/configmap.yaml -f values-2.yaml # values-2.yaml contains configmap config. Works as expected
---
# Source: test/templates/configmap.yaml
apiVersion: v1
data:
  VAR1: val1
  VAR2: val2
kind: ConfigMap
metadata:
  name: configmap

malcolm061990 avatar Sep 15 '22 09:09 malcolm061990

You're using toYaml on an empty dict. This returns {}.

Try:

# common-chartlib/templates/_util.yaml
{{- define "common-chartlib.util.merge" -}}
{{- $top := first . -}}
{{- $overrides := fromYaml (include (index . 1) $top) | default (dict ) -}}
{{- $tpl := fromYaml (include (index . 2) $top) | default (dict ) -}}
{{- $merged := merge $overrides $tpl -}}
{{- if $merged -}}
{{- toYaml $merged -}}
{{- end -}}
{{- end -}}

joejulian avatar Sep 16 '22 00:09 joejulian

@joejulian It works. Thanks! :)

malcolm061990 avatar Sep 27 '22 10:09 malcolm061990