Helm adds release name to dependent charts - kubernetes-helm

I have few dependencies like this
dependencies:
- name: some-chart
version: "1.2.3"
repository: "file://../some-chart"
And I install my chart like so
helm install my-chart .
However, it adds dependent charts my release name. so for example server-0 pod deploys like this
my-chart-some-chart-server-0
If I only install the dependent chart on its own, for example helm install some-chart ../some-chart it deploys 'server-0' like this
some-chart-server-0
Is there a way to deploy dependent charts without adding release name as its intended?

Some time has passed but this may be important information for other users -
As David has explained this can not be changed by helm and comes from the templates.
If you can find the following in the templates
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
then you can use the fullnameOverride for your needs.
You can override the values of the dependency by adding in the parent's (my-chart) values.yaml file the following:
some-chart:
fullnameOverride: some-chart
As a result, the parent's chart name (my-chart) will be dropped from the names of the resources and you will see your server-0 pod as some-chart-server-0 instead of as my-chart-some-chart-server-0.

This naming convention is part of the templates. Helm doesn't add it itself, and you can't change it without changing the templates (or doing complex post-processing).
If you run helm create, it creates a lot of infrastructure for you. Things like the Deployment are generally named
name: {{ include "<CHARTNAME>.fullname" . }}
That template, in turn, is also part of the generated _helpers.tpl file (trimmed slightly)
{{- define "<CHARTNAME>.fullname" -}}
{{- $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 }}
So if you helm install some-chart ../some-chart, the release name (the first some-chart argument) matches the chart name, and you get the "short" form of just the release name; but if you helm install other-chart ../some-chart, you'll get the release-name-chart-name-suffix format.
This has nothing to do with it being a dependency, only the name you're using to install the release. Compare:
helm install some-chart ../some-chart # using its "normal" name
helm install foo ../some-chart # using some other name
helm install my-chart . # "normal" name of parent, not dependency
helm install some-chart . # "normal" name of dependency, not parent
This last case should be interesting: if your parent chart uses the same convention, you will actually see names like some-chart-my-chart-deployment, but the some-chart dependency will see the release and chart names match and so within that dependency you'll just see some-chart-foo.

Related

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.

Helm: override values from dependency chart

I'm using a chart it's using other chart as dependency.
Its chart.yaml file is:
annotations:
category: Infrastructure
apiVersion: v2
appVersion: 3.7.0
dependencies:
- name: common
repository: https://charts.bitnami.com/bitnami
tags:
- bitnami-common
version: 1.x.x
...
It's using this dependecy into its templates like:
apiVersion: v1
kind: Service
metadata:
...
labels: {{- include "common.labels.standard" . | nindent 4 }}
app.kubernetes.io/component: zookeeper
{{- if .Values.commonLabels }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }}
{{- end }}
...
As you can see it's using:
labels: {{- include "common.labels.standard" . | nindent 4 }}
How can I override those values inherited from common.
The Bitnami Common Library Chart is a library chart: it doesn't provide any Kubernetes resources of its own, just a library of template functions you can call (with include or template). That also means it doesn't have its own set of values in the way Helm dependency charts normally do; it uses whatever .Values are in the object you pass to the template.
The implementation of common.labels.standard is pretty straightforward; it provides a set of standard labels that almost every chart should have. You don't usually need to edit these, and you can't change their outputs without copying and pasting the template contents.
Note that one consequence of this is that, if you have a parent chart and a subchart that both include "common.labels.standard" ., they will get different values. .Release.Name will be the same for both, but .Chart.Name will depend on the specific chart being installed (parent or dependency), and in the subchart, .Values will be narrowed to that subchart's settings in the top-level values.
If you need to add labels, this change is easy, and you demonstrate it above. Helm's general operation is to run the template engine naïvely to produce a text document, then hope it's a valid YAML file. If you want additional labels, just include them in the template.
metadata:
labels:
{{-/* the generated labels from the Common chart */}}
{{- include "common.labels.standard" . | indent 4 }}
{{-/* and then any additional labels (correctly indented) */}}
example.com/additional-label: is-present

What is the difference between fullnameOverride and nameOverride in Helm?

I could find both fullnameOverride and nameOverride in Helm chart.Please help clarifying what is the difference between these two with an example.
nameOverride replaces the name of the chart in the Chart.yaml file, when this is used to construct Kubernetes object names. fullnameOverride completely replaces the generated name.
These come from the template provided by Helm for new charts. A typical object in the templates is named
name: {{ include "<CHARTNAME>.fullname" . }}
If you install a chart with a deployment with this name, and where the Chart.yaml file specifies name: chart-name...
helm install release-name ., the Deployment will be named release-name-chart-name
helm install release-name . --set nameOverride=name-override, the Deployment will be named release-name-name-override
helm install release-name . --set fullnameOverride=fullname-override, the Deployment will be named fullname-override
The generated ...fullname template is (one code branch omitted, still from the above link)
{{- define "<CHARTNAME>.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
So if fullnameOverride is provided, that completely replaces the rest of the logic in the template. Otherwise the name is constructed from the release name and the chart name, where nameOverride overrides the chart name.

Helm templating doesn't let me use dash in names

I am creating a helm chart for my app. In the templates directory, I have a config-map.yaml with this in it
{{- with Values.xyz }}
xyz.abc-def: {{ .abc-def }}
{{- end }}
When I try to run helm install I get a
Error: parse error in "config-map.yaml": template:config-map.yaml:2: unexpected bad character U+002D '-' in command.
Is there a way to use dashes in the name and variable for helm?
Might be worth trying using index method:
xyz.abc-def: {{ index .Values.xyz "abc-def" }}
looks like it's still restricted by helm to allow hyphens in variable names (as well in subchart names) and index is a workaround
I faced the same issue because the resource defined had a '-' in its name:
resources:
{{- with .Values.my-value }}
After I removed the '-', the error disappeared:
resources:
{{- with .Values.myvalue }}

How to reference a value defined in a template in a sub-chart in helm for kubernetes?

I'm starting to write helm charts for our services.
There are two things I'm not sure how they are supposed to work or what to do with them.
First: the release name. When installing a chart, you specify a name which helm uses to create a release. This release name is often referenced within a chart to properly isolate chart installs from each other? For example the postgres chart contains:
{{- define "postgresql.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
Which is then used for the service:
metadata:
name: {{ template "postgresql.fullname" . }}
It does look like "myrelease-postgresql" in the end in kubernetes.
I wonder what a good release name is? What is typically used for this? A version? Or some code-name like the ubuntu releases?
Second: referencing values.
My chart uses postgresql as a sub-chart. I'd like to not duplicate the way the value for the name of the postgresql service is created (see snipped above).
Is there a way I can reference the service name of a sub-chart or that template define {{ template "postgresql.fullname" . }} in the parent chart? I need it to pass it into my service as database host (which works if I hardcode everything but that cannot be the meaning of this).
I tried:
env:
- name: DB_HOST
value: {{ template "mychart.postgresql.fullname" . }}
But that lead into an error message:
template "mychart.postgresql.fullname" not defined
I've seen examples of Charts doing similar things, like the odoo chart. But in here that logic how the postgresql host name is created is copied and an own define in the template is created.
So is there a way to access sub-chart names? Or values or template defines?
Thanks!
Update after some digging:
According to Subcharts and Globals the templates are shared between charts.
So what I can do is this:
In my chart in _helpers.tpl I add (overwrite) the postgres block:
{{- define "postgresql.fullname" -}}
{{- $name := .Values.global.name -}}
{{- printf "%s-%s" $name "postgresql" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
So this value is used when the sub-chart is deployed. I cannot reference all values or the chart name in here as it will be different in the sub-chart - so I used a global value.
Like this I know the value of the service that is created in the sub-chart.
Not sure if this is the best way to do this :-/
Are you pulling in postgresql as a subchart of your chart (via your chart's requirements.yaml)? If so, both the postgresql (sub) chart and your chart will have the same .Release.Name - thus, you could specify your container's environment as
env:
- name: DB_HOST
value: {{ printf "%s-postgresql" .Release.Name }}
if you override postgresql's name by adding the following to your chart's values.yaml:
postgresql:
nameOverride: your-postgresql
then your container's env would be:
env:
- name: DB_HOST
value: {{ printf "%s-%s" .Release.Name .Values.postgresql.nameOverride }}
You can overwrite the values of the subchart with the values of the parent chart as described here:
https://helm.sh/docs/chart_template_guide/subcharts_and_globals/
I don't think it's possible (and it also doesn't make sense) to override the template name of the subchart.
What I would do is define the database service name in the .Values files both in the parent and sub charts and let helm override the one in the subchart - that way you will always have the database name in the parent chart. This would however mean that the service name of the database should not be {{ template "name" . }}, but something like {{ .Values.database.service.name }}
mychart/.Values
mysubchart:
service:
name: my-database
mychart/templates/deployment.yaml
env:
- name: DB_HOST
value: {{ .Values.mysubchart.service.name }}
mychart/charts/mysubchart/.Values
service:
name: my-database
mychart/charts/mysubchart/templates/service.yaml:
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.service.name }}
Another way is to use global chart values, also described in https://helm.sh/docs/chart_template_guide/subcharts_and_globals/
For values in the helper.tpl instead of values.yaml
To access a value from a chart you do the following:
{{ template "keycloak.fullname" . }}
To access a value from a sub chart
{{ template "keycloak.fullname" .Subcharts.keycloak }}
You could import values from a sub chart as described here: https://helm.sh/docs/topics/charts/#importing-child-values-via-dependencies.
However there is a caveat. This works not for values defined at the root level in the values.yaml.
See this issue for more information: https://github.com/helm/helm/issues/9817