I'm working in a Chart template for managing deployments for different microservices apps.
On the values file the container Apps are declared in a list, as you can see:
# values.yaml
containerApps:
- name: app1
replicaCount: 1
...
- name: app2
replicaCount: 1
...
- name: app3
replicaCount: 1
...
The template reads the values-file definition in a loop that outputs the K8S YAML file.
{{- range $containerApp := .Values.containerApps }}
{{- with $containerApp }}
...
containers:
- name: {{ .name }}
image: "{{ printf "$.Values.%s.image_repository" .name }}:{{ printf "$.Values.%s.image_tag" .name }}"
replicas: {{ .replicaCount }}
...
...
Besides the values-file, we have also some values being declared using imperative approach via --set-string
parameter.
helm template . --name-template my-app --namespace dev \
--set-string app1.image_repository=my-registry/image-app-1 \
--set-string app1.image_tag=073f799 \
--set-string app2.image_repository=my-registry/image-app-2 \
--set-string app2.image_tag=934df33 \
--set-string app3.image_repository=my-registry/image-app-3 \
--set-string app3.image_tag=k393caf... \
--values values.yaml
The problem is that helm doesn't seem to be able to render the template interpreting the $.Values.%s.image_repository" .name
, generating a wrong output:
# What we expected:
image: my-registry/image-app-1:073f799
...
image: my-registry/image-app-2:934df33
...
image: my-registry/image-app-3:k393caf
...
# What we get...
...
image: $.Values.app1.image_repository:$.Values.app1.image_tag
...
image: $.Values.app2.image_repository:$.Values.app2.image_tag
...
image: $.Values.app3.image_repository:$.Values.app3.image_tag
...
We understand that maybe printf
is not the way to go, and I've tried also index
, which haven't work as well.
If you someone can give us a clue on how to get this working, it would be really appreciated.
Any idea is welcomed.
CodePudding user response:
As you observe, printf
will produce a string but not evaluate it, which is why you're getting the template expressions directly in your output.
I would in fact use index
here. I probably would do this by looking up the top-level value once, and then indexing within that.
{{- range .Values.containerApps }}
{{- $image := index $.Values .name }}
containers:
- name: {{ .name }}
image: "{{ $image.image_repository }}:{{ $image.image_tag }}"
replicas: {{ .replicaCount }}
{{- end }}
range
already resets the special variable .
to the list item, so you do not need the inner with
(unless you expect the list items to potentially be empty). I set $image
to the top-level item from .Values
, and then when you need to use it, you can reference fields in it like $image.image_tag
.