I was looking at the helm range example they have on their docs.
yaml
favorite:
drink: coffee
food: pizza
pizzaToppings:
- mushrooms
- cheese
- peppers
- onions
helm
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
{{- end }}
toppings: |-
{{- range .Values.pizzaToppings }}
- {{ . | title | quote }}
- {{ .Values.favorite.drink }}
{{- end }}
I updated it to have this line - {{ .Values.favorite.drink }} but when I run helm template I get the error
can't evaluate field Values
Is there anyway to access the top level .Values from within the range function and escape the loop?
You can also use a global variable $ that points to the root context
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
{{- end }}
toppings: |-
{{- range $.Values.pizzaToppings }}
- {{ . | title | quote }}
- {{ $.Values.favorite.drink }}
{{- end }}
You can use a variable:
toppings: |-
{{- $drink := .Values.favorite.drink }}
{{- range .Values.pizzaToppings }}
- {{ . | title | quote }}
- {{ $drink }}
{{- end }}
You can assign Values to a variable as well if you prefer.
toppings: |-
{{- $val := .Values }}
{{- range .Values.pizzaToppings }}
- {{ . | title | quote }}
- {{ $val.favorite.drink }}
{{- end }}
Related
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.configMap.name | quote }}
labels:
name: {{ .Values.configMap.name | quote }}
data:
application.yaml: |-
{{ .Files.Get "application.yaml" | indent 4}}
otherFile.csv: |-
{{ .Files.Get "otherFile.csv" | indent 4}}
But I want to make the configmap more generic, so I was thinking on something like this:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.configMap.name | quote }}
labels:
name: {{ .Values.configMap.name | quote }}
data:
{{- range $data := .Values.configMap.data }}
{{ $data }}: |-
{{ .Files.Get $data | indent 4}}
{{- end}}
And in the values.yaml to have something like this:
configMap:
name: app-configmap
data:
- application.yaml
- otherFile.csv
If I don't make it generic it works, but if I try to make it generic I get errors:
executing "app/templates/configmap.yaml" at <.Files.AsConfig>: wrong number of args for AsConfig: want 0 got 1
helm.go:84: [debug] template: app/templates/configmap.yaml:10:9: executing "app/templates/configmap.yaml" at <.Files.AsConfig>: wrong number of args for AsConfig: want 0 got 1
Any hint?
I was wondering if there is any workaround to set a value in a secret and let helm render it before install. The use case is this, I'm using the bitnami chart for rabbitmq and I want to add SSO with my azure active directory, there is the variable advancedConfiguration: |- ... for that purpose but I have to put the configuration in plain text and add it to version control. As you can imagine, I don't want to do that.
The SSO config is like the following json:
advancedConfiguration: |-
[
{rabbit, [
{auth_backends, [rabbit_auth_backend_oauth2, rabbit_auth_backend_internal]}
]},
{rabbitmq_auth_backend_oauth2, [
{resource_server_id, <<"CLIENT_ID">>},
{extra_scopes_source, <<"roles">>},
{key_config, [
{jwks_url, <<"https://login.microsoftonline.com/PROVIDER_ID/discovery/v2.0/keys">>}
]}
]},
{rabbitmq_management, [
{oauth_enabled, true},
{oauth_client_id, "CLIEND_ID"},
{oauth_client_secret, "CLIENT_SECRET"},
{oauth_provider_url, "https://login.microsoftonline.com/PROVIDER_ID"}
]}
].
The PROVIDER_ID, CLIEND_ID and CLIENT_SECRET are the values that I want to hide.
I have read about helm --post-renderer flag, but I am using argocd for deploys and it seems that it is not compatible with that flag.
What options do I have to solve this correctly? Thanks in advance.
This is what the chart does with the value:
apiVersion: v1
kind: Secret
metadata:
name: {{ printf "%s-config" (include "common.names.fullname" .) }}
namespace: {{ include "common.names.namespace" . | quote }}
labels: {{- include "common.labels.standard" . | nindent 4 }}
{{- if .Values.commonLabels }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }}
{{- end }}
{{- if .Values.commonAnnotations }}
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
{{- end }}
type: Opaque
data:
rabbitmq.conf: |-
{{- include "common.tplvalues.render" (dict "value" .Values.configuration "context" $) | b64enc | nindent 4 }}
{{- if .Values.advancedConfiguration }}
advanced.config: |-
{{- include "common.tplvalues.render" (dict "value" .Values.advancedConfiguration "context" $) | b64enc | nindent 4 }}
{{- end }}
As I said, I update the chart and submit a PR. This is solved in the version 11.3.0 using the key advancedConfigurationExistingSecret instead of the previous key.
If you are curious about this here are the details:
Docs: https://artifacthub.io/packages/helm/bitnami/rabbitmq/11.3.0
PR: https://github.com/bitnami/charts/pull/14071
I have a credential.yaml as:
key1: value1
key2: value2
...and so on
how do I add these key, values in credential.yaml as secrets? I am able to add secrets defined in Values object by looping over them as follows:
apiVersion: v1
kind: Secret
metadata:
name: {{ include "ocp-auth.fullname" . }}
labels:
{{- include "ocp-auth.labels" . | nindent 4 }}
type: Opaque
data:
{{- range $key,$value := .Values.secrets }}
{{ $key }}: {{ $value | b64enc | quote }}
{{- end }}
but this is not working for credential.yaml
1、If you use the file name as the key and the file content as the value, you can write as follows:
apiVersion: v1
kind: Secret
metadata:
name: {{ include "ocp-auth.fullname" . }}
labels:
{{- include "ocp-auth.labels" . | nindent 4 }}
type: Opaque
data:
{{ (.Files.Glob "data/credential.yaml").AsSecrets | indent 2 }}
Where data/credential.yaml is the path where the yaml file is located.
Result:
apiVersion: v1
data:
credential.yaml: a2V5MTogdmFsdWUxCmtleTI6IHZhbHVlMg==
kind: Secret
metadata:
name: ocp-auth
type: Opaque
Decode:
# echo "a2V5MTogdmFsdWUxCmtleTI6IHZhbHVlMg==" | base64 -D
key1: value1
key2: value2
2、If you need to use each key in the file as an item in data, you can write as follows:
apiVersion: v1
kind: Secret
metadata:
name: {{ include "ocp-auth.fullname" . }}
type: Opaque
data:
{{- range .Files.Lines "data/credential.yaml" }}
{{- range $i, $v := . | split ":" }}
{{- if eq $i "_0" }}
{{ $v }}:
{{- else }}
{{ $v | trim | b64enc }}
{{- end }}
{{- end }}
{{- end }}
Result:
apiVersion: v1
data:
key1: dmFsdWUx
key2: dmFsdWUy
kind: Secret
metadata:
name: ops-auth
type: Opaque
Decode:
# echo "dmFsdWUx" | base64 -D
value1
# echo "dmFsdWUy" | base64 -D
value2
This way of writing has more restrictions and is not recommended.
First, it can only process a single row of data. And second, it assumes that there is only one ':' in this row.
helm doc
I was reviewing helm template on git repo https://github.com/helm/charts/tree/master/incubator/cassandra
for deploying cassandra in Kubernetes.
I can see in helper template file "_helpers.tpl" , "cassandra.name" has been defined as below , as I can understand whose default value set to name of the Chart , but why .Values.nameOverride used here , without any pipe (just after .Chart.Name) , what is the significant of the same ,I am confused here .
{{- define "cassandra.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
which is used in cassandra/template/configmap.yaml as below
{{- if .Values.configOverrides }}
kind: ConfigMap
apiVersion: v1
metadata:
name: {{ template "cassandra.name" . }}
namespace: {{ .Release.Namespace }}
labels:
app: {{ template "cassandra.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
{{ toYaml .Values.configOverrides | indent 2 }}
{{- end }}
Sprig default function takes two parameters, that's why there is no pipe.
If .Values.nameOverride is empty, .Chart.Name will be used.
Given the following json:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "something.server.fullname" . }}
data:
{{ (.Files.Glob "dashboards/*.json").AsConfig | indent 2 }}
{{ (.Files.Glob "datasources/*.json").AsConfig | indent 2 }}
How can I check if the folder exists and is not empty?
Currently, if the folder is missing or doesn't have any files, helm install will abort with this message:
Error: YAML parse error on domething/charts/grafana/templates/dashboards-configmap.yaml: error converting YAML to JSON: yaml: line 6821: could not find expected ':'
You can pull your Globs out to variables, and then move everything within if blocks, e.g.:
{{- $globdash := .Files.Glob "dashboards/*.json" }}
{{ if $globdash }}
{{- $globdata := .Files.Glob "datasources/*.json" }}
{{ if $globdata }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "something.server.fullname" . }}
data:
{{ ($globdash).AsConfig | indent 2 }}
{{ ($globdata).AsConfig | indent 2 }}
{{ end }}
{{ end }}