How to get the name of a child chart with Helm? - kubernetes

I have a helm chart that requires stable/redis as a child chart. The parent chart needs to expose the redis service as an environment variable.
The redis chart includes a template called redis.fullname. How can I refer to this in my parent chart? I.e. I want something like this in my parent deployment but it doesn't work:
kind: Deployment
spec:
template:
containers:
env:
- name: REDIS_CLUSTER_SERVICE_HOST
value: {{ template "redis.fullname" . }}

You can use '{{ .Release.Name }}-redis' in your parent chart. I had same requirement. This is my example in case you want to take a look ->https://github.com/kubernetes/charts/tree/master/incubator/distribution

Templates are now sharable across parent and child charts.
Refer this - https://github.com/kubernetes/helm/blob/master/docs/chart_template_guide/subcharts_and_globals.md#sharing-templates-with-subcharts
Problem that I see will be:
If your redis.fullname template uses a variable (eg: .Values.commonVariable) that has the same name in both the charts but with different value, then, while referencing it in the parent chart, the value that will be used will be of the parent chart and not the child's.
Consider this:
{{- define "zookeeper.fullname" -}}
{{- printf "%s-%s" (.Values.component) (.Values.subcomponent) -}}
{{- end -}}
Although I want my zookeeper.fullname to be referenced in a kafka (parent) chart. But the .Values.component and .Values.subcomponent will be used of kafka and not that for zookeeper (the subchart) in the case, which totally destroys the idea.
The way out in this specific case will be to use Jainish Shah's answer. But if this is not the case, please don't follow that answer. That destroys the idea of templating. If in any way you ought to change the template function in the subchart, you will also need to modify the value {{ .Release.Name }}-redis in your parent chart. This is not templating.
Link for the aforementioned issue - https://github.com/kubernetes/helm/issues/4314

Improving on Akash's answer, you could try to emulate the correct scope. This also only works if you know what variables the sub-template uses, but might be a bit more stable:
{{ template "redis.fullname" (dict "Values" $.Values.redis "Chart" (dict "Name" "redis") "Release" $.Release) }}

Related

How to add automountServiceAccountToken: false using Helm

I have been trying to add automountServiceAccountToken: false into deployment using helm but my changes are reflecting inside deployment in kubernetes.
I tried below in helpers.tpl
{{- "<chart-name>.automountserviceaccounttoken" }}
{{- default "false" .Values.automountserviceaccounttoken.name }}
{{- end }}
in app-deployment.yaml
automountServiceAccountToken: {{- include "<chart-name>.automountserviceaccounttoken" . }}
in values.yaml
automountServiceAccountToken: false
But I can't see the changes. Please guide
You can give a try with following troubleshooting steps
In the helpers.tpl file you are taking the
automountserviceaccounttoken value from the values.yaml. In
values.yaml you metnioned automountserviceaccounttoken:false but
in the tpl file you are accesing the value like
automountserviceaccounttoken.name there is no attribute called
name under automountserviceaccounttoken in values file. Although you
are using default value in function sometimes it may not include it.
So correct he value in values.yaml.
Debug the deployed heml chart by using a command $helm template template-name. It will download the generated helm template along
with values. Check whether your desired values are reflecting or
not.
In case you are redeploying the chart try upgrading it by $helm upgrade [RELEASE] [CHART] and make sure your values are reflecting.
Before installing the helm chart running with dry-run will give us
the templates with compiled values. So using dry run will helps to
confirm the templates. Command for dry-run $helm install chart-name . --dry-run
Fore more information refer to official document

How to add custom templates to bitnami helm chart?

I'm deploying a spring cloud data flow cluster on kubernetes with helm and the chart from bitnami. This works fine.
Now I need an additional template to add a route. Is there a way to somehow add this or inherit from the bitnami chart and extend it? Of course I'd like to reuse all of the variables which are already defined for the spring cloud data flow deployment.
That chart has a specific extension point for doing things like this. The list of "Common parameters" in the linked documentation includes a line
Name: extraDeploy; Description: Array of extra objects to deploy with the release; Value: []
The implementation calls through to a helper in the Bitnami Common Library Chart that calls the Helm tpl function on the value, serializing it to YAML first if it's not a string, so you can use Helm templating within that value.
So specifically for the Bitnami charts, you can include an extra object in your values.yaml file:
extraDeploy:
- apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: '{{ include "common.names.fullname" . }}'
...
As a specific syntactic note, the value of extraDeploy is a list of either strings or dictionaries, but any templating is rendered after the YAML is parsed; this is different from the normal Helm template flow. In the example above I've included a YAML object, but then quoted a string value that begins with a {{ ... }} template, lest it otherwise be parsed as a YAML mapping. You could also force the whole thing to be a string, though it might be harder to work with in an IDE.
extraDeploy:
- |-
metadata:
name: {{ include "common.names.fullname" . }}
You can just create the YAML template file in the templates folder and it will get deployed with the chart.
You can also edit the existing YAML template accordingly and extend it no need to inherit or much things.
For example, if you are looking forward to adding the ingress into your chart, add ingress template and respective values block in values.yaml file
You can add this whole YAML template in folder : https://github.com/helm/charts/blob/master/stable/ghost/templates/ingress.yaml
and specific values.yaml block for ingress.
Or for example your chart dont have any deployment and you want to add deployment you can write your own template or use form internet.
Deployment : https://github.com/helm/charts/tree/master/stable/ghost/templates
there is deployment.yaml file template and you can get specific variables that the template uses into values.yaml and you have extended the chart successfully.

Include system username in helm charts in helm version 2.14.1

I am using helm version 2.14.1. I have created helm charts for an application that will be deployed by users to test their code on kubernetes cluster. I want to add labels for username values, so I can retrieve deployments by users (deployments by user labels). Is there a way to include system username in helm charts just like we do in Java with System.getProperty("user.name"). My helm template is like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "common.fullname" . }}--{{ Release.name }}
labels:
application: {{ include "common.name" . }}
branch: "{{ Release.name }}"
username: "{{ System.user.name }}" # need to fetch the logged in user from system here
spec:
...
Is there a standard way to achieve this or is there anyway I can allow users to input there usernames from command line while using helm install or helm template commands?
EDIT:
Although, the --set works for me in setting the values for my chart, I also need to set the same value in the dependencies. Something like this:
values.yaml
username: ""
dependency1:
username: {{ .Values.username }}
dependency2:
username: {{ .Values.username }}
...
Of course the above implementation doesn't work. I need to reference the set value in the dependencies as well
This is a community wiki answer based on the comments and posted for better visibility. Feel free to expand it.
You can use the helm template command with a --set option:
--set stringArray set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
--set-file stringArray set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)
--set-string stringArray set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)
The --set parameters have the highest precedence among other methods of passing values into the charts. It means that by default values come from the values.yaml which can be overridden by a parent chart's values.yaml, which can in turn be overridden by a user-supplied values file, which can in turn be overridden by --set parameters.
You can check more details and examples in the official docs.
I have resolved this. Thanks for help #MichaelAlbers and #WytrzymaƂyWiktor. So the solution is as below.
helm template path/to/chart --set global.username=username
And then in all the templates refer to this value as {{ .Values.global.username }}. This works for any dependency chart as well.

Best practices for values in global section of helm values.yaml

Is it best practice to include installation of sub-charts in global part of values.yaml. Example..
Root level values.yaml
global:
foo: bar
subchartA:
enable: true
Or the best practice is to have subcharts out of the global part as shown.
global:
foo: bar
subchartA:
enable: true
Please provide a brief explanation why. Thank you
Subchart configuration settings need to be at the top level, outside a global: block.
At a style level, each chart should be independently installable, whether or not it's used as a subchart. Something like the stable/mysql chart is a reasonable example: you can manually helm install mysql stable/mysql --set mysqlPassword=... without mentioning global. That means when you include it as a dependency its settings need to be under the subchart's key in the values.yaml file.
At a mechanical level, when the subchart is run, the subchartA settings are promoted up to be .Values and then the original global: is merged with that (see Subcharts and Globals). So the subchart itself needs to be aware of the difference
{{/* Option 1 */}}
{{ .Values.global.subchartA.enabled }}
{{/* Option 2 (within subchartA) */}}
{{ .Values.enabled }}
and at the top level you need to use the form that's compatible with the included chart.
(If you browse through the "stable" Helm chart repository you'll see global used fairly sparingly; rabbitmq allows you to declare global.imagePullSecrets but that's close to it.)

How to convert YAML to JSON when saving files into container using Kubernetes Configmap

We are going to write Helm chart and providing configuration file using configmap.
For some reasons our app is using JSON format configuration file. Currently we provide configuration file in Helm chart's values.yaml like this.
conffiles:
app_conf.json:
...(content in YAML)...
And to make it easy to modify, in values.yaml we use YAML format and in configmap's template we did conversion using "toJson",
data:
{{- range $key, $value := .Values.conffiles }}
{{ $key }}: |
{{ toJson $value | default "{}" | indent 4 }}
{{- end -}}
{{- end -}}
So in values.yaml it's YAML, and in configmap it will be JSON, then in container it will be stored into JSON file.
Our question is,
Is there a way to convert YAML to JSON when saving files into container? That is, we hope those configuration content could be 1) YAML in values.yaml 2) YAML in configmap 3) JSON file in container
Thank in advance.
I don't think there is anything out of the box but you do have options, depending upon your motivation.
Your app is looking for json and the configmap is mounted for your app to read that json. Your helm deployment isn't going to modify the container itself. But you could change your app to read yaml instead of json.
If you want to be able to easily see the yaml and json versions you could create two configmaps - one containing yaml and one with json.
Or if you're just looking to be able to see what the yaml was that was used to create the configmap then you could use helm get values <release_name> to look at the values that were used to create that release (which will include the content of the conffiles entry).