Helm: variables in values.yaml - kubernetes

I have a need to use variables inside of values.yaml file:
app:
version: 1.0
my_app1:
tag: {{ .app.version }} <- version taken from appVersion. In my case tag == version
Any help will be really appreciated.

app:
version: 1.0
my_app1:
tag: {{ .Values.app.version }}
{{ .Values.app | first | default .Values.app.version }}
You can also try this EDIT - 2
{{- range $key, $value := .Values.app }}
{{ $key }}: {{ $value }}
{{- end }}

Related

how to loop through in Helm chart

I was trying to iterate through my values.yaml file objects
values.yaml
keyvault:
name: mykv
tenantId: ${tenantId}$
clientid: "#{spid}#"
clientsecret: "#{spsecret}#"
secrets:
- secret1
- secret2
- secret3
So here my requiremnt is to loopthrough each item of above "secrets" to below serviceproviderclass templates, "Data" and objectName fields. But its failing.
What I tried is as below.
{{- define "commonobject.secretproviderclass.tpl" -}}
{{- if eq .Values.secret.enabled true }}
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: {{ $.Release.Name }}-secretproviderclass
labels:
app: {{ $.Release.Name }}
chart: "{{ $.Release.Name }}-{{ .Chart.Version }}"
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
provider: azure
secretObjects:
- data:
{{- range $key, $value := .Values.keyvault }}
{{- range $value.secret }}
- key: { . }
{{- end }}
{{- end }}
secretName: {{ .Values.secret.keyvault.name }}
type: opaque
parameters:
usePodIdentity: "false"
useVMManagedIdentity: "false"
userAssignedIdentityID: ""
keyvaultName: {{ .Values.keyvault.name }}
objects: |
array:
{{- range $key, $value := .Values.keyvault }}
{{- range $value.secret }}
- |
objectName: {{ . }}
objectType: secret
{{- end }}
{{- end }}
tenantId: {{ .Values.keyvault.tenantid }}
{{- end }}
{{- end -}}
{{- define "commonobject.secretproviderclass" -}}
{{- template "commonobject.util.merge" (append . "commonobject.secretproviderclass.tpl") -}}
{{- end -}}
In your values.yaml file, .Values.keyvault is a single object that has keys name, secrets, etc. If you want to iterate through its secrets you just need a single range loop to do that.
secretObjects:
- data:
{{- range .Values.keyvault.secrets }}{{/* <-- only one range loop */}}
- key: { . }
{{- end }}
secretName: {{ .Values.secret.keyvault.name }}
type: opaque
In the double loop you have now, $key and $value get set to each pair from .Values.keyvault in sequence; clientid and #{spid}#, clientsecret and #{spsecret}#, and so on; and then you try to iterate through those (often string-valued) values. For this use you don't need the outer loop.

How do I get the name of a parent element from my values.yaml in a Helm template?

I have a section in my values.yaml that looks like this:
env:
normal:
ENV_VAR_1: value
ENV_VAR_2: otherValue
secret:
secret-location:
ENV_VAR_USERNAME: username
ENV_VAR_PASSWORD: password
different-secret:
ENV_CONN_STRING: my_conn_string
I have a _helpers.tpl function like so:
{{/*
Add environment variables
*/}}
{{- define "helpers.list-env-variables" }}
{{- range $key, $val := .Values.env.normal }}
- name: {{ $key }}
value: {{ $val }}
{{- end }}
{{- range $name := .Values.env.secret }}
{{- }}
{{- range $key, $val := $name }}
- name: {{ $key }}
valueFrom:
secretKeyRef:
name: {{ $name }}
key: {{ $val }}
{{- end }}
{{- end }}
{{- end }}
and it's called in the deployment.yaml like you'd expect:
env:
{{- include "helpers.list-env-variables" . | indent 12 }}
So the normal environment variables get added just fine, but the secret ones don't. It specifies the secretKeyRef.name: value as map[ENV_VAR_USERNAME:username ENV_VAR_PASSWORD:password] instead of secret-key-ref.
helm debug output:
...
env:
- name: ENV_VAR_1
value: value
- name: ENV_VAR_2
value: otherValue
- name: ENV_VAR_PASSWORD
valueFrom:
secretKeyRef:
name: map[ENV_VAR_USERNAME:username ENV_VAR_PASSWORD:password]
key: password
- name: ENV_VAR_USERNAME
valueFrom:
secretKeyRef:
name: map[ENV_VAR_USERNAME:username ENV_VAR_PASSWORD:password]
key: username
- name: ENV_CONN_STRING
valueFrom:
secretKeyRef:
name: map[ENV_CONN_STRING:my_conn_string]
key: my_conn_string
I've already got all these secrets loaded into my K8s cluster (they get shared across a number of microservices, so I don't need to add new secrets which is what the default Helm template seems to want to do) - I just need to reference existing secrets.
My assumption here is that there's something I'm missing in my function to get the value of an element (e.g. "secret-location"), I just can't figure out what it is. If there's a different way I can structure my values.yaml to accomplish this, I'm game for that as well.
When obtaining secret data, it can also be obtained in the form of key-val.
Try replacing _helpers.tpl with the following
{{/*
Add environment variables
*/}}
{{- define "helpers.list-env-variables" }}
{{- range $key, $val := .Values.env.normal }}
- name: {{ $key }}
value: {{ $val }}
{{- end }}
{{- range $k, $v := .Values.env.secret }}
{{- }}
{{- range $key, $val := $v }}
- name: {{ $key }}
valueFrom:
secretKeyRef:
name: {{ $k }}
key: {{ $val }}
{{- end }}
{{- end }}
{{- end }}

Helm Chart environment from values file

I have the following values file:
MYVAR: 12123
MYVAR2: 214123
I want to iterate over them and use them as env variables in my deployment template:
env:
{{- range .Values.examplemap }}
- name: {{ .name }}
value: {{ .value }}
{{- end }}
I tried this
For iterate over a map in helm you can try put this in the values.yaml
extraEnvs:
- name: ENV_NAME_1
value: value123
- name: ENV_NAME_2
value: value123
So in your template you must iterate the extraEnvs like this:
extraEnvs:
{{- range .Values.image.extraEnvs }}
- name: {{ .name | quote }}
value: {{ .value | quote }}
{{- end }}
In the core Go text/template language, the range operator can iterate over either a list or a map. There's specific syntax to assign the key-value pairs in a map to local variables:
env:
{{- $k, $v := range .Values.examplemap }}
- name: {{ $k }}
value: {{ $v }}
{{- end }}

get helm values from yaml inside a range loop

How can I get .Values.someVal from values.yaml file or passed through cli inside a {{ range .Values.smtgĀ }} loop?
for eg.
spec:
containers:
{{ range $k, $v := .Values.smtg }}
- name: {{ $k }}
image: {{ printf "%s:%s" (required "no img" $v) (required "no tag" .Values.someVal) | quote }} <<<--- how can I get .Values.someVal from values.yaml or cli?
{{- end }}
If I try to get them with .Values.smtg I will got : ... at <.Values.someVal>: nil pointer evaluating interface {}
Use $.Values.someVal. The $ will always point to the root context:
spec:
containers:
{{ range $k, $v := $.Values.smtg }}
- name: {{ $k }}
image: {{ printf "%s:%s" (required "no img" $v) (required "no tag" $.Values.someVal) | quote }}
{{- end }}

Helm: overloading global variables on {{ include }} call?

I have a shared metadata block, based on the commons library that I would like to override a name for one specific instance. Is it possible?
metadata:
{{ include "common.metadata" (merge (dict ".Values.fullnameSuffix" "-redirect") .) }} # Doesn't work - How do I add a `-redirect` suffix?
name: {{ include "common.fullname" . }}-redirect # Causes two `name:` attributes
Within common.metadata there is a call to "fullname" as well:
{{ define "common.metadata" -}}
name: {{ template "common.fullname" . }}
namespace: {{ .Release.Namespace }}
{{- end -}}
Is there a way to pass-down a variable override from the first include so that I can override the name:? It's specific only to this chart.
Use set to add a new key/value pair to a dictionary and pass it to slightly modified common.metadata helper function.
values.yaml
fullnameSuffix: redirect
_helpers.tpl
{{- define "common.metadata" -}}
{{- if .suffix }}
name: {{ template "common.fullname" . }}-{{ .suffix }}
{{- else }}
name: {{ template "common.fullname" . }}
{{- end }}
namespace: {{ .Release.Namespace }}
{{- end -}}
manifest.yaml
metadata:
{{- include "common.metadata" (set . "suffix" .Values.fullnameSuffix ) }}
If your fullnameSuffix is empty, name without suffix will be used.