From 46cba8edae22400e008593c02ef54a468f4fb142 Mon Sep 17 00:00:00 2001 From: Musa Misto <64855513+MusaMisto@users.noreply.github.com> Date: Sun, 13 Sep 2026 14:06:09 +0300 Subject: [PATCH] Chart: opt-in service account and pod labels (#303) * feat(chart): opt-in serviceAccount.name and podLabels serviceAccount.name renders serviceAccountName on the pod spec. podLabels adds labels to the pod template only, never the selector, with every value quoted. Both are empty by default, so the default render is byte-identical to before. This lets a release run as an existing ServiceAccount bound to an Azure Workload Identity (serviceAccount.name plus the azure.workload.identity/use pod label) without a Helm post-renderer. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Umepkp3PVYEjJSi9v3j9Xs * fix(chart): quote serviceAccountName and reject reserved podLabels keys A numeric-looking ServiceAccount name such as 123 rendered as a YAML integer, which the API rejects. The podLabels keys app, draft and release duplicated the chart's own pod labels without any render or lint error. app and release are also the selector labels. The chart now fails with a clear message instead. The podLabels examples now quote the --set argument, so the escaped dots survive the shell. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Umepkp3PVYEjJSi9v3j9Xs --------- Co-authored-by: Claude Opus 5 (1M context) (cherry picked from commit 7f9381496046ccde1d62ad4bc3d0d327b916cd9e) --- charts/default/README.md | 2 ++ charts/default/templates/deployment.yaml | 9 +++++++++ charts/default/values.yaml | 11 +++++++++++ 3 files changed, 22 insertions(+) diff --git a/charts/default/README.md b/charts/default/README.md index 373f6889..f629a8c4 100644 --- a/charts/default/README.md +++ b/charts/default/README.md @@ -86,3 +86,5 @@ concerns. |-----|---------|-------------| | `service.type` | `ClusterIP` | Service type. | | `service.port` | `80` | Service port (also the default `HTTPRoute` backend port). | +| `serviceAccount.name` | `''` | Existing ServiceAccount the pod runs as, e.g. one bound to an Azure Workload Identity. Empty renders no `serviceAccountName`. The chart does not create it. | +| `podLabels` | `{}` | Extra labels on the pod template only, never the selector. Values render as strings, e.g. `--set 'podLabels.azure\.workload\.identity/use=true'`. `app`, `draft` and `release` are set by the chart and can't be overridden. | diff --git a/charts/default/templates/deployment.yaml b/charts/default/templates/deployment.yaml index 361c0fc1..e60749b5 100644 --- a/charts/default/templates/deployment.yaml +++ b/charts/default/templates/deployment.yaml @@ -20,9 +20,18 @@ spec: app: {{ template "project.name" . }} draft: {{ .Values.draft | default "draft-app" }} release: {{ .Release.Name }} + {{- range $key, $value := .Values.podLabels }} + {{- if has $key (list "app" "draft" "release") }} + {{- fail (printf "podLabels.%s is set by the chart and can't be overridden" $key) }} + {{- end }} + {{ $key }}: {{ $value | quote }} + {{- end }} annotations: buildID: {{ .Values.buildID | default "" | quote }} spec: + {{- with .Values.serviceAccount.name }} + serviceAccountName: {{ . | quote }} + {{- end }} {{- if .Values.hostAliases }} hostAliases: {{- range .Values.hostAliases }} diff --git a/charts/default/values.yaml b/charts/default/values.yaml index 511a0e30..955d5b46 100644 --- a/charts/default/values.yaml +++ b/charts/default/values.yaml @@ -103,6 +103,17 @@ tolerations: [] affinity: {} +# Existing ServiceAccount for the pod to run as, e.g. one bound to an Azure Workload Identity. +# Empty (default) renders no serviceAccountName, so the namespace's default ServiceAccount is used. +# The chart does not create the ServiceAccount. +serviceAccount: + name: '' + +# Extra labels on the pod template only, never the selector. Values always render as strings. +# app, draft and release are set by the chart and can't be overridden. +# e.g. --set 'podLabels.azure\.workload\.identity/use=true' +podLabels: {} + # db is the connection string for the database db: ""