72 lines
5.4 KiB
Markdown
72 lines
5.4 KiB
Markdown
# ADR-A1 — Cache upstream charts in `helm-templates/` (vs. pull on the fly)
|
|
|
|
> **Status:** Accepted (de facto — current state of the repo).
|
|
> **Repo:** `devops-infra-helm-charts`.
|
|
> **Related:** [docs/architecture.md](../../docs/architecture.md), [SANCTITY_RULES R7](../../docs/global/SANCTITY_RULES.md), [update-chart-version.md](../../docs/platform/procedures/update-chart-version.md), [fork-upstream-chart.md](../../docs/platform/procedures/fork-upstream-chart.md).
|
|
|
|
---
|
|
|
|
## Context
|
|
|
|
Argo CD can render a Helm release in two ways:
|
|
|
|
1. **Pull on the fly** — `Application.spec.source.repoURL` points at an upstream Helm registry; `chart:` names the chart. Argo CD pulls the chart at sync time.
|
|
2. **Cache locally** — the chart lives in a git repo (this one), and `Application.spec.source.path` points at it. Argo CD reads the chart files from git directly.
|
|
|
|
This repo has chosen **caching**. Every chart consumed by Meesho's GKE infra fleet has a directory in `helm-templates/<chart>/` — usually a thin wrapper whose `Chart.yaml` declares the upstream chart as a dependency, with the resolved subchart materialised in `Chart.lock` and `charts/<sub>-<ver>.tgz`.
|
|
|
|
## Decision
|
|
|
|
Cache upstream charts in `helm-templates/` as thin wrapper directories with pinned `dependencies[].version` and a committed `Chart.lock`. Do not configure Argo CD to pull charts directly from upstream registries.
|
|
|
|
## Rationale
|
|
|
|
1. **Repeatable renders.** A chart-version bump in this repo is a git diff; a chart-version "bump" via upstream pull is whatever the registry returns at sync time. Reproducibility on rollback requires the chart bytes to be in git.
|
|
|
|
2. **Air-gapped reviewability.** A reviewer can read the `Chart.yaml`, the `Chart.lock`, and the subchart `.tgz` to know exactly what will render. With on-the-fly pulls, the reviewer trusts the upstream registry hasn't moved a tag.
|
|
|
|
3. **Network independence at sync time.** Argo CD's reconcile loop doesn't need outbound network to upstream registries. If GitHub is reachable, sync works; if it isn't, nothing's deploying anyway.
|
|
|
|
4. **Supply-chain control.** Pinning `dependencies[].version` plus committing `Chart.lock` means the *digest* of each subchart `.tgz` is recorded. A registry compromise that re-publishes a tag with new content is detected by the lockfile mismatch.
|
|
|
|
5. **Forking is local.** When upstream lacks a feature or has a bug, [fork-upstream-chart](../../docs/platform/procedures/fork-upstream-chart.md) is a local edit. No "wait for upstream merge"; the patch lives in our repo until upstream catches up.
|
|
|
|
6. **Render-tooling unchanged.** Reviewer-side `helm template helm-templates/<chart> -f overrides.yaml` works locally without any registry config. Pre-merge validation is just `helm template` against the directory.
|
|
|
|
## Consequences
|
|
|
|
### Accepted
|
|
|
|
- **Repo bigger.** 74 chart directories totalling tens of MBs of subchart `.tgz` files.
|
|
- **Manual update cadence.** A new upstream release isn't picked up automatically. Someone has to bump `dependencies[].version` and run `helm dependency update`. ([update-chart-version](../../docs/platform/procedures/update-chart-version.md))
|
|
- **Forking risk.** Editing `helm-templates/<chart>/templates/` casually creates an accidental fork that gets clobbered next `helm dependency update`. ([SANCTITY_RULES R7](../../docs/global/SANCTITY_RULES.md))
|
|
- **Lock-step requirement.** A `Chart.yaml` bump without a refreshed `Chart.lock` is incomplete — Argo CD reads the lockfile, so the version change silently no-ops.
|
|
|
|
### Mitigated
|
|
|
|
- **Update-chart-version procedure** documents the lock-step requirement explicitly.
|
|
- **Versioned siblings** ([ADR-A2](ADR-A2-blue-green-sibling-pattern.md)) handle major-version bumps without losing the old chart.
|
|
- **Pre-merge `helm template`** catches values incompatibilities before merge.
|
|
|
|
### Open
|
|
|
|
- **Stale charts.** Some directories in `helm-templates/` have no current consumer (`grep -rl '<chart>' helm-overrides` empty). A periodic clean-up exercise has not been formalised.
|
|
- **Subchart `.tgz` size pollution in git history.** Every `helm dependency update` writes a new `.tgz` to `charts/`. Over years, the repo's history grows accordingly. Whether to switch to a Helm-OCI-pull model is an open question.
|
|
- **Chart-bump notification.** Nothing currently alerts the team when an upstream advisory affects a chart we have pinned at an old version. Manual diligence today.
|
|
|
|
## Alternatives considered
|
|
|
|
| Alternative | Why not |
|
|
|-------------|---------|
|
|
| **Pull-on-the-fly from upstream registries.** | Reproducibility, network dependency, supply-chain risk all worse. |
|
|
| **Fully vendor every chart's `templates/`** (no `dependencies[]`, no subchart `.tgz`). | Massive diff churn on every upstream release; worse fork hygiene. |
|
|
| **Use Helm OCI registries** as a middle ground (pull `.tgz` from a private registry instead of git). | Plausible Phase-2 work. Adds an extra service to maintain; doesn't solve forking. Not done today. |
|
|
| **Use `kustomize` instead of Helm.** | Most upstream charts are Helm; rewriting every chart's templates as Kustomize patches would be enormous. |
|
|
|
|
## References
|
|
|
|
- Argo CD Helm chart source docs: <https://argo-cd.readthedocs.io/en/stable/user-guide/helm/>
|
|
- This repo's chart directory layout: [docs/architecture.md §Module boundaries](../../docs/architecture.md).
|
|
- Bump procedure: [update-chart-version](../../docs/platform/procedures/update-chart-version.md).
|
|
- Fork procedure: [fork-upstream-chart](../../docs/platform/procedures/fork-upstream-chart.md).
|