73 lines
4.3 KiB
Markdown
73 lines
4.3 KiB
Markdown
> 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 `<cluster>` × `<app>`, the rendered manifests come from three sources:
|
||
|
||
1. **Chart defaults** — `helm-templates/<chart>/values.yaml`. The upstream values, possibly customized in an intentional fork. This is the lowest precedence.
|
||
2. **Cluster override** — `helm-overrides/<cluster>/<app>/custom-values.yaml`. Helm-merged on top of (1). This is what the agent edits day-to-day.
|
||
3. **Raw manifest sidecars** — `helm-overrides/<cluster>/<app>/<extra>.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 <release> helm-templates/<chart> \
|
||
-f helm-overrides/<cluster>/<app>/custom-values.yaml
|
||
```
|
||
|
||
For wrapper charts (`Chart.yaml` `dependencies:`), refresh subcharts first:
|
||
|
||
```
|
||
helm dependency update helm-templates/<chart>
|
||
```
|
||
|
||
For raw sidecars, validate separately:
|
||
|
||
```
|
||
kubectl apply --dry-run=client -f helm-overrides/<cluster>/<app>/<extra>.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>/` | 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)
|