Files
devops-infra-helm-charts-gcp/claude/04-override-hierarchy.md
T
2026-08-26 03:39:42 +05:30

73 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
> 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)