helm chart conditional install based on a list - kubernetes

I'm trying to find a way to optionally install a manifest based on a list or a map (really don't mind which) in the values file.
in the values file I have
provisioners: ["gp","test"]
and in the manifest I have
{{- if has "test" .Values.provisioners }}
I've also tried
provisioners:
- "gp"
- "test"
and put this in the yaml
{{- if hasKey .Values.provisioners "test" }}
but I can't either way to work, the chart never installs anything.
I feel like I'm missing something pretty basic, but I can't figure out what. Can someone point me in the right direction.

I don't think you shared everything in you template and there might be something else. What you already did is correct, as you in my example below:
# templates/configmap.yaml
{{- if has "test" .Values.provisioners }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: test-config
namespace: default
data:
config.yaml: |
attr=content
{{- end }}
{{- if has "gp" .Values.provisioners }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: gp-config
namespace: default
data:
config.yaml: |
attr=content
{{- end }}
{{- if has "unknown" .Values.provisioners }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: not-templated-config
namespace: default
data:
config.yaml: |
attr=content
{{- end }}
Output of the helm template . against local chart:
---
# Source: chart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test-config
namespace: default
data:
config.yaml: |
attr=content
---
# Source: chart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: gp-config
namespace: default
data:
config.yaml: |
attr=content

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

Config Map in Helm

I am creating a configMap from CSV file using helm tempate but it is getting create different from OC command.
Heml Template:
apiVersion: v1
kind: ConfigMap
metadata:
name: service-config
namespace: {{ .Values.namespace }}
labels:
app: {{ .Values.appname }}
data:
{{- $path := printf "%s/application-config/*" .Values.env }}
{{ (.Files.Glob $path).AsConfig | indent 2 }}
Generated Configmap
kind: ConfigMap
apiVersion: v1
metadata:
name: service-config
namespace: ''
labels:
app.kubernetes.io/managed-by: Helm
data:
esm-instrument-type-map.csv: |-
M-MKT,COB
CMO,COB
MUNI,COB
WARRNT,EQU
PFD,EQU
OC Command :
oc create configmap test-config --from-file= ./esm-instrument-type-map.csv
Generated ConfigMap
kind: ConfigMap
apiVersion: v1
metadata:
name: test-config
namespace: ''
data:
esm-instrument-type-map.csv: "CORP,COB\r\nEQUITY,EQU\r\nGOVT,TRY\r\nMBS,FNM\r\nST-PRD,COB\r\nM-MKT,COB\r\nCMO,COB\r\nMUNI,COB\r\nWARRNT,EQU\r\nPFD,EQU"
As we see, data from the CSV file is in double quotes, when generated by the OC command. I want the same in helm. How can I achieve this?

How to create a kubernetes serviceAccount when I do helm install?

I added this in my values.yaml expecting the serviceAccount to be created when I do the helm install but that did not work, am I missing something ?
helm version v3.9.0
kubernetes version v1.24.0
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: my-service-account
I even tried adding the following (based on https://helm.sh/docs/chart_best_practices/rbac/#helm), with no luck:
rbac:
# Specifies whether RBAC resources should be created
create: true
Thanks
Thanks for the help, I ended up putting this file in the templates directory so it gets processed as you mentioned, I used helm lookup to check if the ServiceAccount is there or not so the first helm install does the installation (https://helm.sh/docs/chart_template_guide/functions_and_pipelines/#using-the-lookup-function)
{{- if not (lookup "v1" "ServiceAccount" "my-namespace" "my-service-account") }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: {{ .Values.namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: my-cluster-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: my-cluster-role-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: my-cluster-role
subjects:
- kind: ServiceAccount
name: my-service-account
namespace: {{ .Values.namespace }}
{{- end }}
You have to create the YAML or helm template into your template directory and helm will create/apply that config file to the K8s cluster.
service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: {{ template "elasticsearch.name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
name: {{ template "elasticsearch.fullname" . }}
Ref :https://github.com/CenterForOpenScience/helm-charts/blob/master/elasticsearch/templates/service-account.yaml
You can add your conditions accordingly to check if create is true or false etc.
Condition or flow control doc : https://helm.sh/docs/chart_template_guide/control_structures/

Usage of Variable Chart.Name in inherited Helm Chart

I've created a helm chart which contains some resources, which are reused in several other Helm charts:
base/templates/base.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
name: {{ .Chart.Name }}
Then I've created a helm chart which inherits the base chart and contains some special resources:
sub1/templates/sub1.yaml
...
name: {{ .Chart.Name }}
Actual Output
In the actual output the resources of the base chart use always the chart name of the base chart.
---
# Source: sub1/templates/sub1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sub1
---
# Source: sub1/charts/base/templates/base.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
name: base
Wanted output
But I want the chart name of the sub chart to be used in the base chart resources.
# Source: sub1/charts/base/templates/base.yaml
...
kind: SecretProviderClass
metadata:
name: sub1
How can I achieve this?
A solution is to reuse the resources via named templates:
base/templates/base.yaml
{{- define "base-lib.secret-provider-class" -}}
apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
name: {{ .Chart.Name }}
{{- end -}}
sub1/templates/sub1.yaml
{{ include "base-lib.secret-provider-class" . }}
---
...

How can I generate a configmap from a directory of files that need to be templated?

I can generate the ConfigMap from the directory but they are not translating the template directives or values. Below is an example of the Release.Namespace template directive not being output in the ConfigMap.
.
|____Chart.yaml
|____charts
|____.helmignore
|____templates
| |____my-scripts.yaml
|____values.yaml
|____test-files
|____test1.txt
---
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-scripts
namespace: {{ .Release.Namespace }}
data:
test.txt: |-
{{ .Files.Get "test-files/test1.txt" | indent 4}}
# test-files/test1.txt
test file
{{ .Release.Namespace }}
When I run helm install . --dry-run --debug --namespace this-should-print here's what I'm getting vs what I'm expecting:
Actual:
---
# Source: test/templates/my-scripts.yaml
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-scripts
namespace: test
data:
test.txt: |-
# test-files/test1.txt
test file
{{ .Release.Namespace }}
Expected:
---
# Source: test/templates/my-scripts.yaml
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-scripts
namespace: test
data:
test.txt: |-
# test-files/test1.txt
test file
this-should-print
Alternatively, I would be interested in every file in a specified directory being output in the format like:
<filename>: |-
<content>
I've found a way of doing it using the tpl function:
---
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-scripts
namespace: {{ .Release.Namespace }}
data:
test.txt: |-
{{ tpl ( .Files.Get "test-files/test1.txt" ) . | indent 4 }}
The new output is exactly as expected:
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-scripts
namespace: this-should-print
data:
test.txt: |-
# test-files/test1.txt
test file
this-should-print
And for bonus points, getting all files from a directory without having to update this list within the config map:
---
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-scripts
namespace: {{ .Release.Namespace }}
data:
{{ tpl (.Files.Glob "groovy-scripts/*").AsConfig . | indent 4 }}
.Files.Get will take the raw contents of those files and dump it into your resulting YAMLs, if you want those file contents to be subject to Helm template rendering themselves, this approach won't work. You can instead create named templates and then include them within other templates.
Directory Structure: tree
.
├── Chart.yaml
├── templates
│   ├── _test1.tpl
│   └── my-scripts.yaml
└── values.yaml
Template: cat templates/my-scripts.yaml
---
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-scripts
namespace: {{ .Release.Namespace }}
data:
test.txt: |-
{{- include "mychart.test1" . | indent 4 }}
Helper: cat templates/_test1.tpl
{{- define "mychart.test1" }}
test file
{{ .Release.Namespace }}
{{- end }}
Result: helm template . --namespace this-should-print
---
# Source: helm/templates/my-scripts.yaml
---
# templates/myscripts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-scripts
namespace: this-should-print
data:
test.txt: |-
test file
this-should-print