Reputation: 1223
I have created common helm charts. In values.yml file, I have set of env variables that need to be set as part of deployment.yaml file.
Snippet of values file.
env:
name: ABC
value: 123
name: XYZ
value: 567
name: PQRS
value: 345
In deployment.yaml, when the values are referred, only the last name/value are set, other values are overwritten. How to read/set all the names/values in the deployment file?
Upvotes: 9
Views: 23023
Reputation: 1726
You could let the chart user decide if he wants to take environment variables from a secret, provide the value, or take it from the downward API in the values.yaml
env:
FOO:
value: foo
BAR:
valueFrom:
secretKeyRef:
name: bar
key: barKey
POD_NAME:
valueFrom:
fieldRef:
fieldPath: metadata.name
and render it in the deployment.yaml
spec:
# ...
template:
# ...
spec:
# ...
containers:
- name: {{ .Chart.Name }}
env:
{{- range $name, $item := .Values.env }}
- name: {{ $name }}
{{- $item | toYaml | nindent 14 }}
{{- end }}
# ...
This is relatively simple and flexible.
It has the shortcoming of not keeping the order of the environment variables. This can break dependent environment variables.
I have written a bit longer story on how to support corrrect ordering as well: An Advanced API for Environment Variables in Helm Charts.
Upvotes: 2
Reputation: 643
It looks like you've made a typo and forgot your dashes. Without the dashes yaml will evaluate env
into a single object instead of a list and overwrite values in unexpected ways.
Your env
should like more like this:
env:
- name: ABC
value: 123
- name: XYZ
value: 567
- name: PQRS
value: 345
- name: SECRET
valueFrom:
secretKeyRef:
name: name
key: key
https://www.convertjson.com/yaml-to-json.htm can help visualize how the yaml is being interpreted and investigate syntax issues.
Upvotes: 2
Reputation: 1223
I've gone through a few iterations of how to handle setting sensitive environment variables. Something like the following is the simplest solution I've come up with so far:
template:
{{- if or $.Values.env $.Values.envSecrets }}
env:
{{- range $key, $value := $.Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- range $key, $secret := $.Values.envSecrets }}
- name: {{ $key }}
valueFrom:
secretKeyRef:
name: {{ $secret }}
key: {{ $key | quote }}
{{- end }}
{{- end }}
values:
env:
ENV_VAR: value
envSecrets:
SECRET_VAR: k8s-secret-name
Pros:
syntax is pretty straightforward
keys are easily mergeable. This came in useful when creating CronJobs with shared secrets. I was able to easily override "global" values using the following:
{{- range $key, $secret := merge (default dict .envSecrets) $.Values.globalEnvSecrets }}
Cons:
This only works for secret keys that exactly match the name of the environment variable, but it seems like that is the typical use case.
Upvotes: 20
Reputation: 4993
This is how I solved it in a common helm-chart I developed previously:
env:
{{- if .Values.env }}
{{- toYaml .Values.env | indent 12 }}
{{- end }}
In the values.yaml:
env:
- name: ENV_VAR
value: value
# or
- name: ENV_VAR
valueFrom:
secretKeyRef:
name: secret_name
key: secret_key
An important thing to note here is the indention. Incorrect indentation might lead to a valid helm-chart (yaml file), but the kubernetes API will give an error.
Upvotes: 4