What is the difference between fullnameOverride and nameOverride in Helm? - kubernetes-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.

Related

Create configmap with outside yaml files for kubernetes

I'm quite new for kubernetes. I am trying to create configmap with using yaml file which was user defined.
helm upgrade --install test --namespace test --create-namespace . -f xxx/user-defined.yaml
user can add any yaml file with using 'f' option.
for example;
cars.yaml
cars:
- name: Mercedes
model: E350
So command will be;
helm upgrade --install test --namespace test --create-namespace . -f xxx/cars.yaml
My question is, I want to create configmap which is name 'mercedes-configmap'
I need to read that values from cars.yaml and create automaticaly configmap with name and data of cars.yaml
Update,
I've created below configmap template;
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.cars.name }}-configmap
data:
{{- range .Files }}
{{ .Files.Get . | toYaml | quote }}
{{- end }}
The only issue that I faced, I couldnt get the whole file data.
Welcome to the community!
I have created a helm template for configmap. It works this way: you can pass configmap name - name and file name - fname where data is stored and/or it can read files from a specific folder.
Please find the template (first 3 lines are commented, it's two working implementations of logic to check values existing):
{{/*
{{ if not (or (empty .Values.name) (empty .Values.fname)) }}
*/}}
{{ if and (not (empty .Values.name)) (not (empty .Values.fname)) }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.name }}-configmap
data:
{{- ( .Files.Glob .Values.fname ).AsConfig | nindent 2 }}
---
{{ end }}
{{ $currentScope := .}}
{{ range $path, $_ := .Files.Glob "userfiles/*.yaml" }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ base $path | trimSuffix ".yaml" }}-configmap
data:
{{- with $currentScope}}
{{ base $path }}: |
{{- ( .Files.Get $path ) | nindent 4 }}
{{- end }}
---
{{ end }}
First part of the template checks if configmap name and file name are set and if so, it renders it. Second part goes to userfiles directory and gets all yamls within.
You find github repo where I shared file examples and configmap.
To render the template with cars2.yaml and with/without files within userfiles directory:
helm template . --set name=cars2 --set fname=cars2.yaml
To render the same template with only files in userfiles directory:
helm template .
P.S. helm v3.5.4 was used
Useful links:
Accessing files in helm
Flow control
File path functions

Helm adds release name to dependent charts

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.

Helm include only existing named template

I'm using Helm for to deploy multiple K8s deployments. In some deployments I need to include extra environment variables, but for the majority of deployment the standard env. variables are enough. I would like to have named template for those deployments that must have extra env. variables.
Can I include a named template only if the named template exist?
Something like this:
{{ range $idx, $svc := .Values.services }}
kind: Deployment
metadata:
name: {{ $svc.name }}
spec:
containers:
- name: {{ $svc.name }}
env:
- name: JAVA_OPTS
- value: {{ $svc.javaOpts }}
# if template_exists (print $svc.name "-env")
{{ include (print $svc.name "-env") . | indent 12 }}
# end
{{- end -}}
It's in pseudo-code. How to do the # if part?
Thank you.
The easiest way would be to add additional key like templateExists: true to your services and check it with a simple if statement in your deployment:
{{- if $svc.templateExists }}
{{ include (print $svc.name "-env") . | indent 8 }}
{{- end -}}
services:
svc1:
templateExists: true
name: svc1
javaOpts: "-Xms128m -Xmx512m"
svc2:
name: svc2
javaOpts: "-Xms256m -Xmx512m"
Here is a solution that I came up now. I check if there are any files in the chart that matches the pattern [service]-env.yaml and if there are then I include the content of that file in the deployment.
{{- range $path, $_ := $f.Glob "**-env.yaml" }}
{{- if contains $svc.app.name $path }}
{{ $f.Get $path | indent 8 }}
{{- end }}
{{- end }}
That way, for services that require extra env. variables we can include a file in files/service-env.yaml and those variables will be added to the deployment. For services that do not require such variables, it's left empty.

Helm change name of deployments artiefacts

I’ve created helm chart which is working as expected, however I want to change the names of the deployed
application
currently for each deployment I got different (random) name and I want it to be a fixed name, how can I do that?
This is the helper
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "unleash.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some K8S name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "unleash.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
This is the outcome of the name after deployment
crabby-ibex-postgresql-0 0/1 Pending 0 1s
crabby-ibex-unleash-86775cdffd-xt575 0/1 ContainerCreating 0 1s
This is the names from the values yaml
replicaCount: 1
namespace: unleash
restartPolicy: Never
name: a-unleash
nameOverride: unleash
e.g. I want it instead of
crabby-ibex-unleash-86775cdffd-xt575
to be like
unleash-service
uleash-postgressql
update
I've added the following to the _helper.tpl
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 26 | trimSuffix "-" -}}
{{- end -}}
and put the following in the values.yml
fullnameOverride: apps
i expect that the artifacts will start with apps and it doesnt work
I don't know, why nobody posted it yet. You can pass the name of the Helm release to the helm install command:
helm install <your_Chart.yaml_directory> -n <release_name>
Based of name crabby-ibex-unleash-86775cdffd-xt575 I guess you are using kind: Deployment for this application, if you change kind to StatefulSet in you yaml you will end up with pod named uleash-postgressql-0, but because of helm you have additional prefix, you could use --name=you_relese_name which will create pod you_relese_name-uleash-postgressql-0.
If you really want to get rid of helm chart prefix you have to set fullnameOverride for every chart you are deploying.
EDIT:
To make use of fullnameOverride you have to define it in your _helpers.tpl file.
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "unleash.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some K8S name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "unleash.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 26 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}

helm getting subchart service names

Whats the best way to get the helm subchart service names to reference into my ingress controller that will sit in the parent chart
values.yaml
---
ingress:
paths:
- serviceName: app-1
path: /app-1/*
port: 8080
- serviceName: app-2
path: /app-2/*
port: 8080
ingress.yaml
---
{{- range .Values.ingress.paths }}
- path: {{ .path }}
backend:
{{- $subchart := .serviceName -}}
serviceName: {{- include "$subchart.fullname" .}}
servicePort: {{ .port }}
{{- end }}
template: no template "$subchart.fullname" associated with template "gotpl"
helm 3.7 version has solved the problem
https://github.com/helm/helm/pull/9957.
You can use like this
{{ template "bar.fullname" .Subcharts.bar }}
How about hardcoded subchart name scoped by release ?
{{ .Release.Name }}-<subchart_name>
I have found that the best way to reference a service name is to override the template that they are using. There are some caveats to doing this however.
The subchart and your chart will have different contexts so they will most likely render the template differently
There are some things that are only available to the subchart
Most charts have a template similar to the one below in their _helpers.tpl file.
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "newchart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $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 }}
{{- end }}
The subchart has different .Values to your chart. We will fix this when we render this template by creating a context that is similar to the subcharts context.
Instead of calling it with the . context we create a new context by replacing the .Values with the subcharts .Values.
{{ template "newchart.fullname" (set (deepCopy .) "Values" .Values.newchart }}
We use deepCopy so that we don't actually change the . context but rather create a new one to use.
The subchart has access to its own .Chart values that we can't replicate. In this case we will have to hardcode the value of .Chart.Name to the template. In this we can just replace it with the chart name newchart.
Once we have done this both nameOverride and fullnameOverride on the subchart will work without you having to manually change anything in your template files.
If the subchart uses the fullname function from _helpers.tpl (provided by helm by default for new charts) you can use this (replace postgresql with the name of the subchart):
{{- $fullName := include "postgresql.fullname" (mustMerge (dict "Chart" (dict "Name" "postgresql") "Values" .Values.postgresql) (deepCopy .)) -}}
It depends on the sub-chart definition!
As an example, elasticsearch chart, see here https://github.com/elastic/helm-charts/blob/master/elasticsearch/templates/service.yaml, is defining 2 services.
Both services name can be declared as value clusterName.