> Per AI Blitz Plan §claude. Layer: 1. Repo: devops-infra-helm-charts. # 04 — Override hierarchy How the per-cluster override file, the chart's default values, and any raw-manifest sidecars compose at deploy time. ## The three layers For a given Argo Application targeting `` × ``, the rendered manifests come from three sources: 1. **Chart defaults** — `helm-templates//values.yaml`. The upstream values, possibly customized in an intentional fork. This is the lowest precedence. 2. **Cluster override** — `helm-overrides///custom-values.yaml`. Helm-merged on top of (1). This is what the agent edits day-to-day. 3. **Raw manifest sidecars** — `helm-overrides///.yaml` (and optionally subdirectories like `computeclass/`, `external-dns-services/`). These are NOT consumed by Helm. Argo applies them directly to the cluster, in the same Application. The Argo Application in the sister repo declares which `path:` (the override directory) and which `helm.valueFiles:` to use. Conventionally the Application points at the override directory and lists `custom-values.yaml`; raw sidecars in the same directory are picked up by Argo's manifest discovery. ## Helm merge semantics Helm performs a **deep merge** of (2) over (1): - Maps merge key-by-key. - Lists are **replaced wholesale**, not merged. This is the most common surprise — to extend an upstream list (`tolerations`, `extraArgs`, `extraEnv`), copy the upstream list into the override and edit there. Don't write a list expecting it to append. - `null` in the override deletes the key set in defaults. If you need surgical list editing rather than wholesale replacement, you must fork the chart and rewrite the template — almost never the right call. See [`../docs/platform/procedures/fork-upstream-chart.md`](../docs/platform/procedures/fork-upstream-chart.md). ## Dry-running the merge Always render before pushing. The command from the root `CLAUDE.md` Quick reference table: ``` helm template helm-templates/ \ -f helm-overrides///custom-values.yaml ``` For wrapper charts (`Chart.yaml` `dependencies:`), refresh subcharts first: ``` helm dependency update helm-templates/ ``` For raw sidecars, validate separately: ``` kubectl apply --dry-run=client -f helm-overrides///.yaml ``` ## Where each piece of config belongs | Config | Goes in | Why | |--------|---------|-----| | Image tag pin (production registry) | `custom-values.yaml` | Per-cluster pinning is the whole point of the override layer. | | `replicaCount`, resource requests | `custom-values.yaml` | Per-cluster capacity tuning. | | `nodeSelector`, `tolerations`, `computeClass` | `custom-values.yaml` | Per-cluster node-pool topology. **Never copy-paste across clusters.** | | `fullnameOverride` | `custom-values.yaml` | Pinned to keep Service DNS / PVC binding stable. **Never change** an existing one. | | Helm-managed Service / Deployment / ConfigMap | chart's `templates/` (don't touch) | Owned by upstream chart. | | External-DNS record bound to a Service the chart doesn't manage | `external-dns-services/*.yaml` raw sidecar | Not part of the chart's surface. | | `ComputeClass` definition (Autopilot) | `computeclass/*-cc.yaml` raw sidecar | Cluster-scoped object the chart can't render. | | StorageClass / PriorityClass | `manifests/storageclass/`, `manifests/priorityclass//` | Cluster-wide singleton, separate from any one Application. | | Secret values | **External Secrets Operator** + GCP Secret Manager / Vault | Never in `custom-values.yaml`. See [`./06-secrets-and-identity.md`](./06-secrets-and-identity.md). | ## Schema details - Override schema: [`../docs/platform/schemas/custom-values-schema.md`](../docs/platform/schemas/custom-values-schema.md) - Raw-sidecar schema: [`../docs/platform/schemas/raw-manifest-sidecar-schema.md`](../docs/platform/schemas/raw-manifest-sidecar-schema.md) - Singleton schema: [`../docs/platform/schemas/storageclass-priorityclass-schema.md`](../docs/platform/schemas/storageclass-priorityclass-schema.md) ## See also - [`./00-overview.md`](./00-overview.md) - [`./05-deploy-lifecycle.md`](./05-deploy-lifecycle.md) - [`../docs/global/coding-guidelines/helm-values.md`](../docs/global/coding-guidelines/helm-values.md)