I'm building a helm chart for my application, and I'm using stable/nginx-ingress
as a subchart. I have a single overrides.yml
file that contains (among other overrides):
nginx-ingress:
controller:
annotations:
external-dns.alpha.kubernetes.io/hostname: "*.{{ .Release.Name }}.mydomain.com"
So, I'm trying to use the release name in the overrides file, and my command looks something like: helm install mychart --values overrides.yml
, but the resulting annotation does not do the variable interpolation, and instead results in something like
Annotations: external-dns.alpha.kubernetes.io/hostname=*.{{ .Release.Name }}.mydomain.com
I installed the subchart by using helm fetch
, and I'm under the (misguided?) impression that it would be best to leave the fetched thing as-is, and override values in it - however, if variable interpolation isn't available with that method, I will have to put my values in the subchart's values.yaml
.
Is there a best practice for this? Is it ok to put my own values in the fetched subchart's values.yaml
? If I someday helm fetch
this subchart again, I'll have to put those values back in by hand, instead of leaving them in an untouched overrides file...
Thanks in advance for any feedback!
Helm 3.x (Q4 2019) now includes more about this, but for chart only, not for subchart (see TBBle's comment)
Milan Masek adds as a comment:
Thankfully, latest Helm manual says how to achieve this.
The trick is:
- enclosing variable in
"
or in a yaml block|-
, and- then referencing it in a template as
{{ tpl .Values.variable . }}
This seems to make Helm happy.
Example:
$ cat Chart.yaml | grep appVersion appVersion: 0.0.1-SNAPSHOT-d2e2f42 $ cat platform/shared/t/values.yaml | grep -A2 image: image: tag: |- {{ .Chart.AppVersion }} $ cat templates/deployment.yaml | grep image: image: "{{ .Values.image.repository }}:{{ tpl .Values.image.tag . }}" $ helm template . --values platform/shared/t/values.betradar.yaml | grep image image: "docker-registry.default.svc:5000/namespace/service:0.0.1-SNAPSHOT-d2e2f42" imagePullPolicy: Always image: busybox
Otherwise there is an error thrown..
$ cat platform/shared/t/values.yaml | grep -A1 image: image: tag: {{ .Chart.AppVersion }} 1 $ helm template . --values platform/shared/t/values.yaml | grep image Error: failed to parse platform/shared/t/values.yaml: error converting YAML to JSON: yaml: invalid map key: map[interface {}]interface {}{".Chart.AppVersion":interface {}(nil)}
For Helm subchart, TBBle adds to issue 2133
@MilanMasek 's solution won't work in general for subcharts, because the context
.
passed intotpl
will have the subchart's values, not the parent chart's values.It happens to work in the specific example this ticket was opened for, because
.Release.Name
should be the same in all the subcharts.
It won't work for.Chart.AppVersion
as in thetpl
example.There was a proposal to support tval in #3252 for interpolating templates in values files, but that was dropped in favour of a lua-based Hook system which has been proposed for Helm v3: #2492 (comment)
That last issue 2492 include workarounds like this one:
You can put a placeholder in the text that you want to template and then replace that placeholder with the template that you would like to use in yaml files in the template.
For now, what I've done in the CI job is run helm template on the
values.yaml
file.
It works pretty well atm.
cp values.yaml templates/ helm template $CI_BUILD_REF_NAME ./ | sed -ne '/^# Source: templates\/values.yaml/,/^---/p' > values.yaml rm templates/values.yaml helm upgrade --install ...
This breaks if you have multiple
-f values.yml
files, but I'm thinking of writing a small helm wrapper that runs essentially runs that bash script for eachvalues.yaml
file.
fsniper illustrates again the issue:
There is a use case where you would need to pass deployment name to dependency charts where you have no control.
For example I am trying to set
podAffinity
for zookeeper. And I have an application helm chart which sets zookeeper as a dependency.In this case, I am passing pod
antiaffinity
to zookeeper via values. So in my appsvalues.yaml
file I have azookeeper.affinity
section.
If I had the ability to get the release name inside the values yaml I would just set this as default and be done with it.But now for every deployment I have to override this value, which is a big problem.
I found the issue on github -- it is not supported yet: https://github.com/kubernetes/helm/issues/2133