how to make helm template render template only once - kubernetes-helm

i have values.yml that can render deployment, there are two components. here my values.yml example
workers:
- name: default-worker
metadata:
name: default
component: web-server
serviceAccountName: default-worker-account
- name: data-worker
metadata:
name: data
component: web-server
serviceAccountName: data-worker-account
this is the deployment.yml
{{- if $.Values.workers -}}
{{- range $worker := $.Values.workers -}}
{{- $fullName := printf "%s-%s" (include "chart-app.fullname" $) $worker.name -}}
{{- $name := printf "%s-%s" (include "chart-app.name" $) $worker.name -}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $fullName }}
it will render two deployment of worker deployment.
# Source: rails-app/templates/worker.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: default-worker
# Source: rails-app/templates/worker.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: data-worker
....
how to just render one deployment? for example just
# Source: rails-app/templates/worker.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: data-worker
i need to extract the result but i only need one deployment rendered
thanks in advance

Something like this would do the trick
{{- if $.Values.workers -}}
{{- with (first $.Values.workers) -}}
{{- $fullName := printf "%s-%s" (include "chart-app.fullname" $) .name -}}
{{- $name := printf "%s-%s" (include "chart-app.fullname" $) .name -}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $fullName }}
{{end}}
{{end}}

Related

combination of helper template and values in helm

I am new to helm charts and I am building helm chart to deploy an app on kubernetes, as part of it I have created a deployment template as below,
{{- $outer := . -}}
{{- range $index, $service := .Values.myservices}}
{{- with $outer }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $service.name }}
labels:
{{- include "myhelm.labels" $ | nindent 4 }}
spec:
.
.
.
{{- end }}
{{- end }}
Here I am using a template "myhelm.labels", which is defined in _helpers.tpl as below,
{{/*
Common labels
*/}}
{{- define "myhelm.labels" -}}
helm.sh/chart: {{ include "myhelm" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
I like to include some more labels provided in the values.yaml as below
myservices:
api:
name: "com-api"
labels:
app: "com-api"
selectorLabels:
app: "com-cp"
podAnnotations: {}
container:
image: "com-api"
port: 24000
name: "api"
nodeSelector:
app: "com-cp-api"
affinity: {}
tolerations: {}
ui:
name: "com-ui"
labels:
app: "com-ui"
selectorLabels:
app: "com-ui"
podAnnotations: {}
container:
image: "com-ui"
port: 23000
name: "ui"
nodeSelector:
app: "com-cp-ui"
affinity: {}
tolerations: {}
Along with "myhelm.labels" (common labels) I also want to include service specific labels like $service.labels.
Please help me, how can I do it ?
I am able to add specific labels one by one like,
labels:
{{- include "dlc-project-service-control-plane.labels" $ | nindent 4 }}
app: {{ $service.labels.app }}
But, I am looking for a solution, if I have multiple labels under $service.labels in values.yaml and want to add all of them in a single statement in deployment template.
Please share the code snippet if you already know the solution, it helps.
Thanks
I am able to achieve it using the toYaml, below is the code snippet,
{{- $outer := . -}}
{{- range $index, $service := .Values.myservices}}
{{- with $outer }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $service.name }}
labels:
{{- include "myhelm.labels" $ | nindent 4 }}
{{- toYaml $service.labels | nindent 4 }}
spec:
.
.
.
{{- end }}
{{- end }}

what is the manifest yaml file equivalent of the create configmap --from-env-file command

I need to create a manifest configmap yaml file (configmap template helm) that execute the same operation that we get when we run the command
kubectl create configmap config-env-file --from-env-file=config.properties
Please note that I must retrieve the parameters from 'properties' file (and not from configmap file)
config.properties file
# dummy param
node=2
pod=3
when i run the command that create the the configmap from the config.properties file, I get:
apiVersion: v1
data:
node: "2"
pod: "3"
kind: ConfigMap
metadata:
name: config-env-file
namespace: default
I need to reproduce this result by building a configmap helm chart
thanks
I am by far not an expert on templating, but this works (I took your example literally):
apiVersion: v1
kind: ConfigMap
metadata:
name: config-env-file
namespace: default
data:
{{- $content := .Files.Get "resources/config.properties" }}
{{- range $line := splitList "\n" $content }}
{{ $parts := split "=" $line }}
{{- $key := printf "%s" $parts._0 }}
{{- $value := printf "%s" $parts._1 }}
{{- printf "%s:" $key }} {{ quote $value }}
{{- end }}

How to render list (slice) of string as list in yaml file by Helm Chart

I have a list or (slice) of string data for example [string1, string2, string3].
I want to render it in list fashion in yaml file as
- string1
- string2
- string3
How can I do that?
I have tried
{{- range $val := $list }}
- {{ $val }}
{{- end }}
but it renders following as multiple line of strings
- |-
- string1
- string2
- string2
any idea? thank you in advance
You may use formatted string output to solve the problem.
eg.
values.yaml
arr:
- string1
- string2
- string3
_helpers.tpl
{{/*
Print string from list split by ,
*/}}
{{- define "print.list" -}}
{{- range $idx, $val := $.Values.arr -}}
{{- if $idx }}
{{- print ", " -}}
{{- end -}}
{{- $val -}}
{{- end -}}
{{- end -}}
The template you want to render, for example comfigmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "test.fullname" . }}
data:
test: [{{- include "print.list" .}}]
output
piVersion: v1
kind: ConfigMap
metadata:
name: test
data:
test: [string1, string2, string3]
---↓ 2022-01-05 update ↓---
values.yaml
arr:
- string1
- string2
- string3
The template you want to render, for example comfigmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "test.fullname" . }}
data:
test: |
{{- toYaml $.Values.arr | nindent 4 }}
output
piVersion: v1
kind: ConfigMap
metadata:
name: test
data:
test: |
- string1
- string2
- string3
no pipe
helm --dry-run --debug template test .
The template you want to render, for example comfigmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "test.fullname" . }}
data:
test:
{{- toYaml $.Values.arr | nindent 4 }}
output
piVersion: v1
kind: ConfigMap
metadata:
name: test
data:
test:
- string1
- string2
- string3
range
{{- range $i, $v := $.Values.arr }}
- {{ $v }}
{{- end }}
output
- string1
- string2
- string3

Pass JSON config variable to helm using --set [duplicate]

This question already has answers here:
How to pass entire JSON string to Helm chart value?
(5 answers)
Closed 1 year ago.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-configmap
data:
{{- range $key, $value := .Values.envVars }}
{{ $key }}: {{ $value | quote }}
{{- end }}
Running
helm upgrade my-app --install --set envVars.CREDS='{"key":"val"}'
with the above configmap results in a configmap as follows:
CREDS = ["key":"val"]
So instead of a JSON, it's an array.
What do I need to configure to pass it as a JSON?
That looks fine, based on this answer regarding json objects representation in yamls: https://stackoverflow.com/a/33989696/11874278
If you want to achieve another thing - this key as json string you could do:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-configmap
data:
{{- range $key, $value := .Values.envVars }}
{{ $key }}: >
{{ $value }}
{{- end }}

Helm range without leaving global scope

I need to loop through a list of instances and create 1 stateful set for every instance. However, inside range I then limit myself to the scope of that loop. I need to access some global values in my statefulset.
I've solved it by just putting all global objects I need in an env variable but... this very seems hacky.
What is the correct way to loop through ranges while still being able to reference global objects?
Example of my loop
{{- $values := .Values -}}
{{- $release := .Release -}}
{{- range .Values.nodes }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ $release.Name }} <-- Global Scope
labels:
.
.
.
env:
- name: IP_ADDRESS
value: {{ .ip_address }} <-- From range scope
.
.
.
{{- end }}
Example of values
# Global
image:
repository: ..ecr.....
# Instances
nodes:
- node1:
name: node-1
iP: 1.1.1.1
- node2:
name: node-2
iP: 1.1.1.1
When entering a loop block you lose your global context when using .. You can access the global context by using $. instead.
As written in the Helm docs -
there is one variable that is always global - $ - this variable will always point to the root context. This can be very useful when you are looping in a range and need to know the chart's release name.
In your example, using this would look something like:
{{- range .Values.nodes }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ $.Release.Name }}
labels:
.
.
.
env:
- name: IP_ADDRESS
value: {{ .ip_address }}
.
.
.
{{- end }}
The question is about the global scope, but it is possible to keep access to any outer scope by storing it, like this:
{{- $outer := . -}}
Then, if you use named variables for the range, like this:
{{- range $idx, $node := .Values.nodes }}
You don't need ., so you can restore the outer scope, like this:
{{- with $outer -}}
In your example, using this would look something like:
{{- $outer := . -}}
{{- range $idx, $node := .Values.nodes }}
{{- with $outer -}}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Release.Name }}
labels:
.
.
.
env:
- name: IP_ADDRESS
value: {{ $node.ip_address }}
.
.
.
{{- end }}
If you need to access the global scope only, simply add {{- with $ -}} will do.
{{- range $idx, $node := .Values.nodes }}
{{- with $ -}}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Release.Name }}
labels:
.
.
.
env:
- name: IP_ADDRESS
value: {{ $node.ip_address }}
.
.
.
{{- end }}
{{- end }}
The best way is not to call many external objects inside the loop.
you can declare release name at the top in a variable to overcome this issue:
{{- $release_name := .Release.Name -}}