Values context in an included helm named template - kubernetes-helm

We have a helm chart that contains named templates to be used by other templates.
Originally, the helm chart containing the named templates has no "values.yaml" file, as all it has are "_function.tpl" files. But now, we would like to use a "values.yaml" file to define some values there instead of having to be passed by the caller like so after defining the dependency in the Chart.yaml.
{{ include "libchart.velero" (list . .Values.velero )}}
The named template then would have a definition, which converts those contexts passed as list to $root and "velero", so we can work comfortably with the caller passed context, like so:
{{- define "libchart.velero" -}}
{{- $root := index . 0 -}}
{{- $velero := index . 1 -}}
But question is, how could I define and consume the variables define in the "values.yaml" file present in the chart that contains the definition of the named template itself.
I've tried using things like {{ $.Values.local }} and {{ .Values.local }} to access "locally to the named template" defined variable, but no luck with those.

With that construction, the top-level Helm object (which contains Values, Release, Namespace, etc. fields) is in the $root variable inside the template.
{{-/*
Call with a list of two items, the top-level Helm object and the
.Values.velero chart configuration.
Outputs something only if the `local` top-level value is set.
*/-}}
{{- define "libchart.velero" -}}
{{- $root := index . 0 -}}
{{- $velero := index . 1 -}}
{{- if $root.Values.local -}} {{-/* <-- like this */-}}
... {{ $velero }} ...
{{- end -}}
{{- end -}}

Related

Kubernetes Helm: Helpers includes accessible in one file, but not another

In one directory are numerous files, there is a _helpers.tpl file as well as .yaml templates that we use to deploy different services. To simplify my issue and what I'm working with:
_helpers.tpl
backup.yaml
writer.yaml
There is a variable defined in the _helpers.tpl file that is accessible in backup.yaml, but the exact same line of code referring to the exact same variable in writer.yaml gives the following error:
Error: template: temp-chart/templates/template.yaml:8:23: executing "temp-chart/templates/template.yaml" at <include "account" .>: error calling include: template: no template "account" associated with template "gotpl"
I did not create this project, so I'm wondering if there was an error in the initial setup of the writer.yaml file or something was overlooked? Are there any steps required in configuring the helpers file or the templates that ensures they can access one another?
_helpers.tpl
{{- define "account" -}}
{{- if .Values.backup.account -}}
{{- .Values.backup.account-}}
{{- else -}}
{{- .Values.buildVals.accountId -}}
{{- end -}}
{{- end -}}
backup.yaml and writer.yaml are identical:
account: {{ include "account" . }}

Helm 2.x - use subchart as template

Depending on a subchart via requirements.yaml results in the template being rendered. I'm aware that I can use aliases to have more than one copy of a subchart, but is there a way to prevent the subchart to be rendered by default and instead included as a template, along the lines of:
{{- $root := . }}
{{- range $i, $service := .Values.services }}
---
{{ $k8sDeployment := (include "MY_SUBCHART_NAME" (dict "top" $root "deployment" $service)) | fromYaml }}
{{ include "deployment" (dict "top" $root "deployment" $k8sDeployment) }}
---
{{ $k8sService := (include "MY_SUBCHART_NAME2" $service) | fromYaml }}
{{ include "service" (dict "top" $root "service" $k8sService) }}
{{- end -}}
No, there's no way to do this. Helm dependencies (both in Helm 2 and Helm 3) work only as things that are installed in the cluster under the same Helm release name. Without using something like a post-renderer to manipulate the produced YAML, there's no way to include only part of a dependency chart or to re-include its Kubernetes objects with different parameters.
One could imagine the subchart being specifically designed to be used this way. The subchart would have to provide the templates you're trying to call, and its templates/*.yaml file would call those templates with standard values inside an if block, and then your parent chart could depend on the subchart with a value that disabled its normal output. Most charts aren't built this way, though.

What is, and what use cases have the dot "." in helm charts?

im currently going through the docs of helm, and there have been at least 3 different uses for the dot (.), is there any specific definition for it? and does it have something in common with the bash use (actual folder/files)?
some cases in the documentation
This print the accesed files in the range called before?
{{- $files := .Files }}
{{- range tuple "config1.toml" "config2.toml" "config3.toml" }}
{{ . }}: |-
{{ $files.Get . }}
{{- end }}
This tells "mychart.app" to use the files in the current folder (bash-like behaviour)
{{ include "mychart.app" . | indent 4 }}
and this, i guess it takes the values from the whole folder??? i guess this is not correct since is not working (it has been made by another employee back then and i have to fix it)
{{- define "read.select-annot" -}}
{{- range $key, $value := . }}
{{ $key }}: {{ $value }}
{{- end }}
{{- end }}
thanks for the help
In general, . in Helm templates has nothing to do with files or directories.
The Helm templating language uses Go's text/template system. There are a couple of different ways a period character can appear there.
First of all, . can be a character in a string:
{{- range tuple "config1.toml" "config2.toml" "config3.toml" }}
{{/* ^^^^^^^^^^^^
this is a literal string "config1.toml" */}}
...
{{- end }}
Secondly, . can be a lookup operator. There aren't any solid examples in your question, but a typical use is looking up in values. If your values.yaml file has
root:
key: value
then you can expand
{{ .Values.root.key }}
and the . before root and key navigates one level down in the dictionary structure.
The third use, and possibly the one that's confusing you, is that . on its own is a variable.
{{ . }}
You can do field lookups on it, and you have some examples of that: .Files is the same as index . "Files", and looks up the field "Files" on the object ..
You use . as a variable in several places:
{{- $files := .Files }} {{/* Get "Files" from . */}}
{{ . }} {{/* Write . as a value */}}
{{ include "mychart.app" . }} {{/* Pass . as the template parameter */}}
. is tricky in that it has somewhat contextual meaning:
At the top level, Helm initializes . to an object with keys Files, Release, Values, and Chart.
In a defined template, . is the parameter to the template. (So when you include or template, you need to pass . down as that parameter.)
In a range loop, . is the current item being iterated on.
In a with block, . is the matched item if it exists.
In particular, the interaction with range can be tricky. Let's look at a simplified version of your loop:
# {{ . }}
{{- range tuple "config1.toml" "config2.toml" "config3.toml" }}
- {{ . }}
{{- end }}
Outside the range loop, . is probably the top-level Helm object. But inside the range loop, . is the file name (each value from the tuple in turn). That's where you need to save values from . into local variables:
{{/* We're about to invalidate ., so save .Files into a variable. */}}
{{- $files := .Files }}
{{- range tuple "config1.toml" "config2.toml" "config3.toml" }}
{{/* This . is the filename from the "tuple" call */}}
{{ . }}: |-
{{/* Call .Get, from the saved $files, passing the filename .
as the parameter */}}
{{ $files.Get . }}
{{- end }}

Is it possile to create yaml object from helm from file

I want to iterate over the Yaml list which is defined in the file, and use it in Job. For example i have
test.yaml
list:
- first element
- second element
In _helpers.tpl i can define
something like
{{- define "mychart.list" -}}
{{ .Files.Get "test.yaml"| toYaml }}
{{- end }}
And then in Job i want do something like
{{- $lists := include "mychart.list" . }}
{{- range $element := $lists.list}}
apiVersion: batch/v1
kind: Job
metadata:
and then use the $element.
But when i am trying to do the dry-run with --debug it complains about
at <$lists.list>: can't evaluate field list in type string.
Looks like whole value is coming as string rather than Yaml, does it needs explicit call to Yaml parser ? If yes, is there a way to do that ?
BTW i have also tried various combinations of
{{- $lists := include "mychart.list" . | toYaml }}
or loading the file inline, but none of them helps.
I can put the list in Values.yaml, but don't want to do that purposely.
Any help is really appreciated.
Just putting for future reference, if someone comes and have look.
There's fromYaml function, which is undocumented. I found it hard way, but that solved the isssue.
{{- $lists := include "mychart.list" . | fromYaml}}

Helm include templates

Please! Is it possible to squash multiple helm templates into one and then refer to it as a one-liner in a deployment file?
EG:
{{- define "foo.deploy" -}}
value:
{{- include "foo.1" . | nindent 6 }}
{{- include "foo.2" . | nindent 6 }}
{{- include "foo.3" . | nindent 6 }}
And then do an {{- include "foo.deploy" . }} in a separate deployment file.
Which should then contain foo.1, foo.2 and foo.3, and their respective definitions.
As opposed to literally writing out all three different 'includes' especially if you've got loads.
Much appreciated,
Thanks,
A named template (sometimes called a partial or a subtemplate) is simply a template defined inside of a file, and given a name. We’ll see two ways to create them, and a few different ways to use them.
Template names are global. As a result of this, if two templates are declared with the same name the last occurrence will be the one that is used. Since templates in subcharts are compiled together with top-level templates, it is best to name your templates with chart specific names. A popular naming convention is to prefix each defined template with the name of the chart: {{ define "mychart.labels" }}.
More information about named templates you can find here: named-template.
Proper configuration file should look like:
{{/* Generate basic labels */}}
{{- define "mychart.labels" }}
labels:
generator: helm
date: {{ now | htmlDate }}
{{- end }}
In your case part of file should looks like:
{{- define "foo.deploy" -}}
{{- include "foo.1" . | nindent 6 }}
{{- include "foo.2" . | nindent 6 }}
{{- include "foo.3" . | nindent 6 }}
{{ end }}