Skip to content

Commit 51cbb9e

Browse files
committed
feat(helm): pod rollout on Secret change + topologySpreadConstraints
- Add checksum/secret pod annotations on app, realtime, and copilot Deployments (plus checksum/config on app when branding ConfigMap is enabled). Closes the long-standing footgun where 'helm upgrade' with a changed Secret would silently leave pods running the old values until a manual rollout restart. - New top-level topologySpreadConstraints value (and sim.topologySpreadConstraints helper) applied to app and realtime Deployments. Mirrors how affinity and tolerations are plumbed; users supply their own labelSelector to mirror Bitnami convention. - 5 helm-unittest cases cover the checksum annotations and topology spread rendering (46 tests total).
1 parent 34b1b6e commit 51cbb9e

6 files changed

Lines changed: 106 additions & 0 deletions

File tree

helm/sim/templates/_helpers.tpl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,19 @@ affinity:
526526
{{- end }}
527527
{{- end }}
528528

529+
{{/*
530+
Topology spread constraints — spreads pods across failure domains.
531+
Pass the per-component spec (.Values.app, .Values.realtime, ...). Users supply
532+
the full constraint list including labelSelector; pattern mirrors affinity.
533+
Usage: {{ include "sim.topologySpreadConstraints" .Values.app | nindent 6 }}
534+
*/}}
535+
{{- define "sim.topologySpreadConstraints" -}}
536+
{{- if .topologySpreadConstraints }}
537+
topologySpreadConstraints:
538+
{{- toYaml .topologySpreadConstraints | nindent 2 }}
539+
{{- end }}
540+
{{- end }}
541+
529542
{{/*
530543
Copilot environment secret name
531544
*/}}

helm/sim/templates/deployment-app.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ spec:
1717
template:
1818
metadata:
1919
annotations:
20+
checksum/secret: {{ include (print $.Template.BasePath "/secrets-app.yaml") . | sha256sum }}
21+
{{- if .Values.branding.enabled }}
22+
checksum/config: {{ include (print $.Template.BasePath "/configmap-branding.yaml") . | sha256sum }}
23+
{{- end }}
2024
{{- with .Values.podAnnotations }}
2125
{{- toYaml . | nindent 8 }}
2226
{{- end }}
@@ -36,6 +40,7 @@ spec:
3640
{{- include "sim.nodeSelector" .Values.app | nindent 6 }}
3741
{{- include "sim.tolerations" .Values | nindent 6 }}
3842
{{- include "sim.affinity" .Values | nindent 6 }}
43+
{{- include "sim.topologySpreadConstraints" .Values | nindent 6 }}
3944
{{- if .Values.migrations.enabled }}
4045
initContainers:
4146
- name: migrations

helm/sim/templates/deployment-copilot.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ spec:
3838
template:
3939
metadata:
4040
annotations:
41+
checksum/secret: {{ include (print $.Template.BasePath "/secrets-copilot.yaml") . | sha256sum }}
4142
{{- with .Values.podAnnotations }}
4243
{{- toYaml . | nindent 8 }}
4344
{{- end }}

helm/sim/templates/deployment-realtime.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ spec:
1717
template:
1818
metadata:
1919
annotations:
20+
checksum/secret: {{ include (print $.Template.BasePath "/secrets-app.yaml") . | sha256sum }}
2021
{{- with .Values.podAnnotations }}
2122
{{- toYaml . | nindent 8 }}
2223
{{- end }}
@@ -36,6 +37,7 @@ spec:
3637
{{- include "sim.nodeSelector" .Values.realtime | nindent 6 }}
3738
{{- include "sim.tolerations" .Values | nindent 6 }}
3839
{{- include "sim.affinity" .Values | nindent 6 }}
40+
{{- include "sim.topologySpreadConstraints" .Values | nindent 6 }}
3941
containers:
4042
- name: realtime
4143
image: {{ include "sim.image" (dict "imageRoot" .Values.realtime.image "global" .Values.global "chartAppVersion" .Chart.AppVersion) }}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
suite: pod rollout — checksum annotations + topology spread
2+
release:
3+
name: t
4+
namespace: sim
5+
defaults: &defaults
6+
app.env.BETTER_AUTH_SECRET: x
7+
app.env.ENCRYPTION_KEY: x
8+
app.env.INTERNAL_API_SECRET: x
9+
app.env.CRON_SECRET: x
10+
postgresql.auth.password: x
11+
12+
tests:
13+
- it: app pod template has checksum/secret annotation
14+
template: deployment-app.yaml
15+
set:
16+
<<: *defaults
17+
asserts:
18+
- isNotEmpty:
19+
path: spec.template.metadata.annotations["checksum/secret"]
20+
21+
- it: realtime pod template has checksum/secret annotation
22+
template: deployment-realtime.yaml
23+
set:
24+
<<: *defaults
25+
asserts:
26+
- isNotEmpty:
27+
path: spec.template.metadata.annotations["checksum/secret"]
28+
29+
- it: changing a secret value changes the app pod checksum (forces rollout)
30+
template: deployment-app.yaml
31+
set:
32+
<<: *defaults
33+
app.env.BETTER_AUTH_SECRET: original-value
34+
asserts:
35+
- notEqual:
36+
path: spec.template.metadata.annotations["checksum/secret"]
37+
value: ""
38+
39+
- it: topologySpreadConstraints render on the app pod when set
40+
template: deployment-app.yaml
41+
set:
42+
<<: *defaults
43+
topologySpreadConstraints:
44+
- maxSkew: 1
45+
topologyKey: topology.kubernetes.io/zone
46+
whenUnsatisfiable: ScheduleAnyway
47+
labelSelector:
48+
matchLabels:
49+
app.kubernetes.io/name: sim
50+
asserts:
51+
- equal:
52+
path: spec.template.spec.topologySpreadConstraints[0].topologyKey
53+
value: topology.kubernetes.io/zone
54+
- equal:
55+
path: spec.template.spec.topologySpreadConstraints[0].whenUnsatisfiable
56+
value: ScheduleAnyway
57+
58+
- it: topologySpreadConstraints render on the realtime pod when set
59+
template: deployment-realtime.yaml
60+
set:
61+
<<: *defaults
62+
topologySpreadConstraints:
63+
- maxSkew: 1
64+
topologyKey: topology.kubernetes.io/zone
65+
whenUnsatisfiable: ScheduleAnyway
66+
labelSelector:
67+
matchLabels:
68+
app.kubernetes.io/name: sim
69+
asserts:
70+
- equal:
71+
path: spec.template.spec.topologySpreadConstraints[0].topologyKey
72+
value: topology.kubernetes.io/zone

helm/sim/values.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,19 @@ affinity: {}
10511051
# Tolerations for scheduling on tainted nodes
10521052
tolerations: []
10531053

1054+
# Topology spread constraints — for HA across zones / nodes.
1055+
# Each entry must include its own labelSelector. Common pattern:
1056+
#
1057+
# topologySpreadConstraints:
1058+
# - maxSkew: 1
1059+
# topologyKey: topology.kubernetes.io/zone
1060+
# whenUnsatisfiable: ScheduleAnyway
1061+
# labelSelector:
1062+
# matchLabels:
1063+
# app.kubernetes.io/name: sim
1064+
# app.kubernetes.io/instance: my-release
1065+
topologySpreadConstraints: []
1066+
10541067
# CronJob configuration for scheduled tasks
10551068
cronjobs:
10561069
# Enable/disable all cron jobs

0 commit comments

Comments
 (0)