data node empty in Configmap on helm install - kubernetes-helm

These are my helm charts:
# helm/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
mycfgmap: |-
{{ .Files.Get (printf "environments/configmap.%s\n.yaml" .Values.namespace) | indent 4 }}
# helm/environments/values.dev.yaml
namespace: dev
# helm/environments/configmap.dev.yaml
MY_ENV_VARIABLE_1: "true"
This is how I am installing my helm charts:
helm install --dry-run --debug --create-namespace -n dev -f helm/environments/values.dev.yaml my-test-release helm
This is the output I am getting:
# Source: helm/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
mycfgmap: |-
---
I am expecting this to be in the data node (as defined in my configmap.dev.yaml):
MY_ENV_VARIABLE_1: "true"
Please note that I have alredy tried these for helm/templates/config.yaml:
{{ .Files.Get (printf "../environments/configmap.%s\n.yaml" .Values.namespace) | indent 4 }}
# and
{{ .Files.Get (printf "environments/configmap.%s.yaml" .Values.namespace) | indent 4 }}
and it doesn't work. I have also looked at similar questions answered on SO, but my problem seem to be something else.

I can see from your message that the file you have used for configmap yaml is # helm/environments/config.dev.yaml. Please rename it to configmap.dev.yml. And change your printf statement like below. Once you make these changes, things should work fine.
{{ .Files.Get (printf "environments/configmap.%s.yaml" .Values.namespace) | indent 4 }}

Related

defining url in helm chart values as a variable

I have the following yaml file in values.yaml
ingress:
enabled: false
url: {{ .Release.Name }}.abc.com
but when I lint it with helm it shows the following error
Error: cannot load values.yaml: error converting YAML to JSON: yaml: line 14: did not find expected key
if I put "{{ .Release.Name }}.abc.com" it then the .Release.Name is not working. Im new to helm. thank you
helm doesn't support re-rendering like this, you need to use named template to make it work.
Named Template
e.g.
templates/_helpers.tpl
...
{{- define "ingressConfig" -}}
ingress:
enabled: false
url: {{ .Release.Name }}.abc.com
{{- end -}}
...
Use it in other templates like configmap.yaml
templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test
data:
data: |-
{{- include "ingressConfig" . | nindent 4 }}
cmd
helm template --debug test .
output
apiVersion: v1
kind: ConfigMap
metadata:
name: test
data:
data: |-
ingress:
enabled: false
url: test.abc.com

Helm create secret from env file

Kubectl provides a nice way to convert environment variable files into secrets using:
$ kubectl create secret generic my-env-list --from-env-file=envfile
Is there any way to achieve this in Helm? I tried the below snippet but the result was quite different:
kind: Secret
metadata:
name: my-env-list
data:
{{ .Files.Get "envfile" | b64enc }}
It appears kubectl just does the simple thing and only splits on a single = character so the Helm way would be to replicate that behavior (helm has regexSplit which will suffice for our purposes):
apiVersion: v1
kind: Secret
data:
{{ range .Files.Lines "envfile" }}
{{ if . }}
{{ $parts := regexSplit "=" . 2 }}
{{ index $parts 0 }}: {{ index $parts 1 | b64enc }}
{{ end }}
{{ end }}
that {{ if . }} is because .Files.Lines returned an empty string which of course doesn't comply with the pattern
Be aware that kubectl's version accepts barewords looked up from the environment which helm has no support for doing, so if your envfile is formatted like that, this specific implementation will fail
I would like to use env files but it seems to be helm doesn't support that yet.
Instead of using an env file you could use a yaml file.
I mean to convert from this env file
#envfile
MYENV1=VALUE1
MYENV2=VALUE2
to this yaml file (verify the yaml format, always it should be an empty space after the colon)
#envfile.yaml
MYENV1: VALUE1
MYENV2: VALUE2
After this, you should move the envfile.yaml generated in the root folder of your helm chart (same level of values yaml files)
You have to set up your secret.yaml in this way:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
annotations:
checksum/config: {{ (tpl (.Files.Glob "envfile.yaml").AsSecrets . ) | sha256sum }}
type: Opaque
data:
{{- $v := $.Files.Get "envfile.yaml" | fromYaml }}
{{- range $key, $val := $v }}
{{ $key | indent 2 }}: {{ $val | b64enc }}
{{- end}}
We are iterating in the data property the envfile.yaml generated and encoding the value to base64. The result secret will be the next:
kubectl get secret my-secret -o yaml
apiVersion: v1
data:
MYENV1: VkFMVUUx
MYENV2: VkFMVUUy
kind: Secret
metadata:
annotations:
checksum/config: 8365925e9f9cf07b2a2b7f2ad8525ff79837d67eb0d41bb64c410a382bc3fcbc
creationTimestamp: "2022-07-09T10:25:16Z"
labels:
app.kubernetes.io/managed-by: Helm
name: my-secret
resourceVersion: "645673"
uid: fc2b3722-e5ef-435e-85e0-57c63725bd8b
type: Opaque
Also, I'm using checksum/config annotation to update the secret object every time a value is updated.

Files.Get concatenated string value appears empty after helm template in Kubernetes Configmap

I'm using a configmap with a dynamic filename defined as below. However, after I do helm template the value for the filename is empty:
apiVersion: v1
kind: ConfigMap
metadata:
name: krb5-configmap
data:
krb5.conf: |-
{{ .Files.Get (printf "%s//krb5-%s.conf" .Values.kerberosConfigDirectory .Values.environment) | indent 4 }}
kerberosConfigDirectory: kerberos-configs (set in Values.yaml)
Folder structure:
k8s:
templates
configmap.yaml
kerberos-configs
krb5-dev.conf
After helm template the data value looks like this:
data:
krb5.conf: |-
--
I can't figure out why the value for the filename is empty. Note that I'm able to run the helm template command successfully.
You have an extra / and extra indentation in you file. Working example:
apiVersion: v1
kind: ConfigMap
metadata:
name: krb5-configmap
data:
krb5.conf: |-
{{ .Files.Get (printf "%s/krb5-%s.conf" .Values.kerberosConfigDirectory .Values.environment) | indent 4 }}

How to create ConfigMap from directory using helm

I have a folder with 3 json files in a postman folder. How can I create a ConfigMap using a Helm yaml template?
kubectl create configmap test-config --from-
file=clusterfitusecaseapihelm/data/postman/
The above solution works, but I need this as yaml file as I am using Helm.
Inside a Helm template, you can use the Files.Glob and AsConfig helper functions to achieve this:
{{- (.Files.Glob "postman/**.json").AsConfig | nindent 2 }}
Or, to give a full example of a Helm template:
apiVersion: v1
kind: ConfigMap
metadata:
name: test-config
data:
{{- (.Files.Glob "postman/**.json").AsConfig | nindent 2 }}
See the documentation (especially the section on "ConfigMap and secrets utility functions") for more information.

Helm chart restart pods when configmap changes

I am trying to restart the pods when there is a confimap or secret change. I have tried the same piece of code as described in: https://github.com/helm/helm/blob/master/docs/charts_tips_and_tricks.md#automatically-roll-deployments-when-configmaps-or-secrets-change
However, after updating the configmap, my pod does not get restarted. Would you have any idea what could has been done wrong here?
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ template "app.fullname" . }}
labels:
app: {{ template "app.name" . }}
{{- include "global_labels" . | indent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ template "app.name" . }}
release: {{ .Release.Name }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yml") . | sha256sum }}
https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments Helm3 has this feature now. deployments are rolled out when there is change in configmap template file.
Neither Helm nor Kubernetes provide a specific rolling update for a ConfigMap change. The workaround has been for a while is to just patch the deployment which triggers the rolling update:
kubectl patch deployment your-deployment -n your-namespace -p '{"spec":{"template":{"metadata":{"annotations":{"date":"$(date)"}}}}}'
And you can see the status:
kubectl rollout status deployment your-deployment
Note this works on a nix machine. This is until this feature is added.
Update 05/05/2021
Helm and kubectl provide this now:
Helm: https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments
kubectl: kubectl rollout restart deploy WORKLOAD_NAME
it worked for me, below is the code snippet from my deployment.yaml file, make sure your configmap and secret yaml file are same as what referred in the annotations:
spec:
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/my-configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/my-secret.yaml") . | sha256sum }}
I deployed pod with configmap with this feature https://helm.sh/docs/howto/charts_tips_and_tricks/#automatically-roll-deployments.
When I edited the configmap at runtime , it didn't trigger the roll-deployment.