helm template values and set variables - kubernetes

I have this section in my service template. I want, if variable publicIP is defined, define loadBalancerIP.
{{- if .Values.publicIP }}
loadBalancerIP: {{ .Values.publicIP }}
{{- end }}
in my values.$environment.yml
I define
publicIP: null
And I need to define publicIP when I do helm install, for example:
helm install release release/path -f values.$environment.yml -—set publicIP=127.0.0.1
But it isn't working. What can I do to define publicIP and it defines in my template?

I am not sure I understand the question but if you want to set an individual parameter you need to do it with
"--set"
eg : helm install --set foo=bar ./mychart
What is the name of your values.yml? values.$environment.yml?
Try also command like this
helm install release release/path -f --values {YOUR_VALUES_FILE}.yml --set publicIP=127.0.0.1
and be sure to use --, you seem in the example provided to use a weird special character much longer than a normal dash.
And second is publicIP a root parameter?
if you have something like this in {YOUR_VALUES_FILE}.yml
root
node: null
you need to set it like this :
helm install release release/path -f --values {YOUR_VALUES_FILE}.yml --set root.node=value

Related

Helm template - Overriding values file

I am currently trying to test some changes, specifically to see if a chart picks up/inherits changes from a top level values file. This top level values file should override any settings in the values file for this chart. To test this, I am trying to use the following command:
helm template --values path/to/top/level/values.yaml path/to/chart > output.yaml
However, when viewing the output for this, the chart still retains the values defined in the chart, and not the values that have been set in the top level values file.
I have tried a number of variations of this command, such as:
helm template path/to/chart --values path/to/top/level/values.yaml > output.yaml
helm template -f path/to/chart/values.yaml --values path/to/top/level/values.yaml > output.yaml
helm template path/to/top/level/values.yaml --values path/to/chart > output.yaml
Am I using this command correctly? Is what I am trying to achieve only possible when doing a helm install or upgrade? e.g. https://all.docs.genesys.com/PrivateEdition/Current/PEGuide/HelmOverrides
Overriding values from a parent (you call it top-level) chart mychart works like a charm and exactly as described in the Helm docs.
A values.yaml in folder mychart/charts/mysubchart
dessert: cake
can be overriden by a values.yaml in folder mychart
mysubchart:
dessert: ice cream
Any directives inside of the mysubchart section will be sent to the mysubchart chart.
Rendering the parent (top-level) chart works like that:
helm template mychart -f mychart/values.yaml
What if what you want is to combine from 2 yaml files, is it possible?
Example:
values.yaml:
blackBoxSidecar:
enabled: true
targets:
- target: esb:443
module: tcp_connect
values-namespace.yaml:
blackBoxSidecar:
targets:
- target: rabbitmq-namespace:443
module: tcp_connect
What I want to get is:
blackBoxSidecar:
enabled: true
targets:
- target: esb:443
module: tcp_connect
- target: rabbitmq-namespace:443
module: tcp_connect

How can I pass imagePullSecrets, as it is defined in the default template, to helm via set commands

When you run helm create mychart it has imagePullSecrets defined like this:
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }
In default values file it looks like it's passing it a blank array:
imagePullSecrets: []
I already have a bunch of charts built from this default template that have this setting. Previously I didn't need to use imagePullSecrets so I just left it as is, but now I have some cases where I want to set this at deploy time via the cli.
Helm supports arrays now but this doesn't seem to work:
--set "mychart.imagePullSecrets[0].name={reg-creds}"
Returns:
Error: UPGRADE FAILED: error validating "": error validating data: ValidationError(Deployment.spec.template.spec.imagePullSecrets[0].name): invalid type for io.k8s.api.core.v1.LocalObjectReference.name: got "array", expected "string"
Then I tried passing a string:
--set "mychart.imagePullSecrets='- name: reg-creds'"
Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: ValidationError(Deployment.spec.template.spec.imagePullSecrets): invalid type for io.k8s.api.core.v1.PodSpec.imagePullSecrets: got "string", expected "array"
These error messages are infuriating. Is it possible to set this value with --set so I can avoid refactoring all my charts?
The helm install --set syntax is unique and complex. One unusual bit of syntax there is that a value {foo,bar} in curly braces sets the value to an array. In your example, then, --set object.path={value} sets the value to a single-element array; the error you see is that it needs to be a string instead.
That means a simple workaround here is to remove the curly braces on the right-hand side of --set. There is also a --set-string option that forces the value to be interpreted as a string, even if it contains curly braces or commas.
helm install ... --set "mychart.imagePullSecrets[0].name=reg-creds"
# no curly braces around the value ^^^^^^^^^
It might be clearer, and have a more standard syntax, to use a YAML file to provide this value instead.
# image-pull-secrets.yaml
imagePullSecrets:
- name: reg-creds
You can include this in a per-environment values file, or pass it as a standalone values file. In either case you'd use the helm install -f option to supply the file. It's fine to have multiple helm install -f values files.
helm install ... -f image-pull-secrets.yaml

Syntax Error in Yaml File - missed comma between flow collection entries

We have an application deployed in AKS , the kubernetes version we were using is 1.15 now we want to upgrade the Kubernetes to 1.16, I notice that some of the APIs have been deprecated in 1.16.We have deployment.yaml file in which I had to change the from
apiVersion: extensions/v1beta1 to apiVersion: apps/v1 for Deployment.
after doing this change I see that the deployment YAML is failing lint test for another entry :
- name : APP_HOST
{{- range $host := .Values.ingress.hosts }}
value: {{ $host }}
{{- end }}
Error :
npx yaml-lint yamllint deployment.yaml
npx: installed 45 in 14.04s
× YAML Lint failed for deployment.yaml
× missed comma between flow collection entries at line 88, column 11:
{{- range $host := .Values.ingress ...
Can some one help me with the syntax needed for this. Mind you it was working fine before. Not sure if I have added and extra space or corrupted the file.
Thanks
The syntax you have looks like a correct Helm template, including correct whitespace controls. However, it is not valid YAML; the template {{ ... }} syntax looks at least a little bit like an inline mapping { key: value }, and this confuses the linter.
You can't run the un-rendered Helm template files through yamllint or another plain YAML validator. You can run helm template to render the template to plain text, and then run yamllint on that. The current version of Helm will try to parse the produced YAML as it generates it, so just running helm template will give you some protection against whitespace errors.

How to pass a file using values file in helm chart?

I want to pass a certificate to the helm chart and currently I am passing using --set-file global.dbValues.dbcacertificate=./server.crt but instead i want to pass the file in values file of helm chart.
The Values.yaml file reads
global:
dbValues:
dbcacertificate: <Some Way to pass the .crt file>
According to the relevant documentation, one must pre-process a file that is external to the chart into a means that can be provided via --set or --values, since .Files.Get cannot read file paths that are external to the chart bundle.
So, given the following example template templates/secret.yaml containing:
apiVersion: v1
kind: Secret
data:
dbcacertificate: {{ .Values.dbcacertificate | b64enc }}
one can use shell interpolation as:
helm template --set dbcacertificate="$(cat ./server.crt)" .
or, if shell interpolation is not suitable for your circumstances, you can pre-process the certificate into a yaml compatible format and feed it in via --values:
$ { echo "dbcacertificate: |"; sed -e 's/^/ /' server.crt; } > ca-cert.yaml
$ helm template --values ./ca-cert.yaml .

overriding values in kubernetes helm subcharts

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!
I found the issue on github -- it is not supported yet:
https://github.com/kubernetes/helm/issues/2133
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 into tpl 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 the tpl 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 each values.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 apps values.yaml file I have a zookeeper.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.
Update Oct. 2022, from issue 2133:
lazychanger proposes
I submitted a plugin to override values.yaml with additional templates.
See lazychanger/helm-viv: "Helm-variable-in-values" and its example.