i have a helm deployment.yaml
template file containing the below:
containers:
{{- include "app.container" (merge .Values.app $) | nindent 8 }}
{{- range $k, $v := .Values.extraContainers }}
{{- $nameDict := dict "name" $k -}}
{{- include "app.container" (mustMergeOverwrite $.Values.app $nameDict $v) | nindent 8 }}
{{- end }}
a values.yaml
that looks like this:
The values under .Values.app
are intended to be the values for the main container, but should also act as the defaults for the extraContainers when values are not specified explicitly for the extraContainers.
app:
image:
name: xxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/foobar
tag: latest
probes:
readinessProbe:
path: /_readiness
enabled: true
livenessProbe:
path: /_liveness
enabled: true
port: 80
resources:
limits:
cpu: 10Mi
memory: 2Gi
requests:
cpu: 10Mi
memory: 2Gi
extraContainers:
extra-container1:
image:
name: xxxxxxxxx.dkr.ecr.eu-west-1.amazonaws.com/foobar-extra
tag: test
command:
- sleep
- 10
envVars:
- name: FOO
value: BAR
port: 8080
probes:
readinessProbe:
path: /extraContainerReadinessPath
port: 8080
livenessProbe:
path: /extraContainerLivenessPath
port: 8080
resources:
limits:
cpu: 1000Mi
memory: 1Gi
requests:
cpu: 1000Mi
memory: 1Gi
extra-container2:
image:
name: 211161777205.dkr.ecr.eu-west-1.amazonaws.com/foobar-two
tag: latest
command:
- sleep
- 10
probes:
readinessProbe:
enabled: false
livenessProbe:
enabled: false
and a helper containing the below:
{{/*
app container base
*/}}
{{- define "app.containerBase" -}}
- name: {{ .name | default "app" }}
image: {{ .image.name }}:{{ .image.tag }}
{{- if .command }}
command:
{{- range .command }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- if .args }}
args:
{{- range .args }}
- {{ . | quote }}
{{- end }}
{{- end }}
env:
{{- range .envVars }}
- name: {{ .name }}
{{- with .value }}
value: {{ . | quote }}
{{- end }}
{{- with .valueFrom }}
valueFrom:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- end -}}
{{/*
app container
*/}}
{{- define "app.container" -}}
{{- include "app.containerBase" . }}
imagePullPolicy: {{ .image.pullPolicy | default "Always" }}
{{- if .port }}
ports:
- containerPort: {{ .port }}
protocol: {{ .protocol | upper }}
{{- end }}
{{- if .probes.readinessProbe.enabled }}
readinessProbe:
{{- if .probes.readinessProbe.custom }}
{{- toYaml .probes.readinessProbe.custom | nindent 4 }}
{{- else }}
httpGet:
port: {{ .probes.readinessProbe.port | default .port }}
path: "{{ required "app.probes.readinessProbe.path is required" .probes.readinessProbe.path }}"
scheme: HTTP
initialDelaySeconds: {{ .probes.readinessProbe.initialDelaySeconds | default "40" }}
periodSeconds: {{ .probes.readinessProbe.periodSeconds | default 10 }}
timeoutSeconds: {{ .probes.readinessProbe.timeoutSeconds | default "30" }}
successThreshold: {{ .probes.readinessProbe.successThreshold | default "3" }}
failureThreshold: {{ .probes.readinessProbe.failureThreshold | default "2" }}
{{- end }}
{{- end }}
{{- if .probes.livenessProbe.enabled }}
livenessProbe:
{{- if .probes.livenessProbe.custom }}
{{- toYaml .probes.livenessProbe.custom | nindent 4 }}
{{- else }}
httpGet:
port: {{ .probes.livenessProbe.port | default .port }}
path: "{{ required "app.probes.livenessProbe.path is required" .probes.livenessProbe.path }}"
scheme: HTTP
initialDelaySeconds: {{ .probes.livenessProbe.initialDelaySeconds | default "40" }}
periodSeconds: {{ .probes.livenessProbe.periodSeconds | default "10" }}
timeoutSeconds: {{ .probes.livenessProbe.timeoutSeconds | default "30" }}
successThreshold: {{ .probes.livenessProbe.successThreshold | default "1" }}
failureThreshold: {{ .probes.livenessProbe.failureThreshold | default "2" }}
{{- end }}
{{- end }}
{{- if .probes.startupProbe.enabled }}
startupProbe:
{{- if .probes.startupProbe.custom }}
{{- toYaml .probes.startupProbe.custom | nindent 4 }}
{{- else }}
httpGet:
port: {{ .probes.startupProbe.port | default .port }}
path: "{{ required "app.probes.startupProbe.path is required" .probes.startupProbe.path }}"
scheme: HTTP
initialDelaySeconds: {{ .probes.startupProbe.initialDelaySeconds | default "40" }}
periodSeconds: {{ .probes.startupProbe.periodSeconds | default "10" }}
timeoutSeconds: {{ .probes.startupProbe.timeoutSeconds | default "30" }}
successThreshold: {{ .probes.startupProbe.successThreshold | default "1" }}
failureThreshold: {{ .probes.startupProbe.failureThreshold | default "2" }}
{{- end }}
{{- end }}
resources:
limits:
cpu: {{ .resources.limits.cpu | default "100m" | quote }}
memory: {{ .resources.limits.memory | default "128Mi" | quote }}
{{- if .resources.limits.ephemeralStorage }}
ephemeral-storage: {{ .resources.limits.ephemeralStorage }}
{{- end }}
requests:
cpu: {{ .resources.requests.cpu | default "100m" | quote }}
memory: {{ .resources.requests.memory | default "128Mi" | quote }}
{{- if .resources.requests.ephemeralStorage }}
ephemeral-storage: {{ .resources.requests.ephemeralStorage }}
{{- end }}
{{- end -}}
running helm template results in the below:
containers:
- name: app
image: xxxxx.dkr.ecr.eu-west-1.amazonaws.com/foobar:latest
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
readinessProbe:
httpGet:
port: 80
path: "/_readiness"
scheme: HTTP
initialDelaySeconds: 40
periodSeconds: 10
timeoutSeconds: 30
successThreshold: 3
failureThreshold: 2
livenessProbe:
httpGet:
port: 80
path: "/_liveness"
scheme: HTTP
initialDelaySeconds: 40
periodSeconds: 10
timeoutSeconds: 30
successThreshold: 1
failureThreshold: 2
resources:
limits:
cpu: "10Mi"
memory: "2Gi"
requests:
cpu: "10Mi"
memory: "2Gi"
- name: extra-container1
image: xxxx.dkr.ecr.eu-west-1.amazonaws.com/foobar-extra:test
command:
- "sleep"
- "10"
env:
- name: FOO
value: "BAR"
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
readinessProbe:
httpGet:
port: 8080
path: "/extraContainerReadinessPath"
scheme: HTTP
initialDelaySeconds: 40
periodSeconds: 10
timeoutSeconds: 30
successThreshold: 3
failureThreshold: 2
livenessProbe:
httpGet:
port: 8080
path: "/extraContainerLivenessPath"
scheme: HTTP
initialDelaySeconds: 40
periodSeconds: 10
timeoutSeconds: 30
successThreshold: 1
failureThreshold: 2
resources:
limits:
cpu: "1000Mi"
memory: "1Gi"
requests:
cpu: "1000Mi"
memory: "1Gi"
- name: extra-container2
image: xxxxx.dkr.ecr.eu-west-1.amazonaws.com/foobar-two:latest
command:
- "sleep"
- "10"
env:
- name: FOO
value: "BAR"
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
resources:
limits:
cpu: "1000Mi"
memory: "1Gi"
requests:
cpu: "1000Mi"
memory: "1Gi"
As you can see, extra-container2
should have the default resource limits/requests of 10Mi and 2Gi, but they seem to have the values from the previous iteration of the loop(extra-container1). The same occurs with the presence of the FOO=BAR env var present in extra-container2, although it is only set in extra-container1.
essentially it looks like values from the first loop in the range, are persisting into the second loop, when the second loop doesn't explicitly set those values.
thank you for reading