Files
devops-infra-argo-config-gcp/wiki/analyses/ADR-I2-incubator-pattern.md
T
2026-08-26 04:03:34 +05:30

85 lines
4.1 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.
# ADR-I2: Why the Incubator + Generic Chart Pattern
> Architecture Decision Record for `devops-infra-argo-config`.
>
> **Status:** Accepted (in production use)
>
> **Layer:** 1-T reference. This ADR documents the load-bearing architectural decision behind the repo's structure.
---
## Context
`devops-infra-argo-config` manages ArgoCD `Application` resources for infrastructure tooling across ~19 Kubernetes clusters. The early approach was direct Application YAML files — one file per tool per cluster.
**Problem with the direct approach:**
- Adding a tool to 15 clusters = 15 new YAML files
- Each file had ~40 lines of near-identical boilerplate (metadata, syncPolicy, finalizers, source URLs)
- Updating a field common to all clusters (e.g., `targetRevision`) required editing 15 files
- Drift between files was hard to detect and frequently occurred
---
## Decision
Adopt the **App-of-Applications incubator pattern**:
1. One **parent Application** per cluster (the "incubator"). It points at a Helm chart in this repo + a values file.
2. One **generic Helm chart** (`generic-argo-apps-chart/`) that templates child Applications from a list.
3. One **values file** per cluster that defines `clusterSpec`, `teamSpec`, `argocdSpec`, and the `appSpec[]` list.
To add a tool to a cluster: add one entry to `appSpec[]` in the values file. The chart renders the Application. No boilerplate.
---
## Consequences
### Positive
| Benefit | Detail |
| ------- | ------ |
| **Single editing surface** | Adding or removing a tool = one list entry in one values file |
| **Consistent Application shape** | All child Applications are rendered by the same template → same syncPolicy, finalizers, label schema |
| **Drift is visible** | Comparing `appSpec[]` across values files is trivially scriptable |
| **Chart-level changes propagate instantly** | Update `generic-argo-apps-chart/` once → all clusters reflect it on next sync |
| **Naming is deterministic** | Application names are generated by the template, not hand-typed |
### Negative / constraints
| Constraint | Detail |
| ---------- | ------ |
| **`generic-argo-apps-chart/` changes are fleet-wide** | A bug in the template breaks ALL clusters simultaneously — HIGH RISK edits |
| **Three-file invariant** | Adding a cluster requires coordinated creation of incubator + values file + helm-overrides folder in the sister repo |
| **Cross-repo dependency** | `appSpec[].chartDir` and `valuesDir` must exist in `devops-infra-helm-charts` — the repos are coupled |
| **No per-cluster template customization** | If a cluster needs a fundamentally different Application shape (different syncPolicy, different project), the generic chart must be extended rather than overridden per cluster |
---
## Alternatives considered
### Alternative 1: Direct Application YAMLs per tool per cluster
Rejected. Scale problem: 50 tools × 19 clusters = 950 files. Drift is unmanageable.
### Alternative 2: ApplicationSet with cluster generators
Considered for a future phase. ApplicationSet would allow truly declarative fleet management (define a tool once, it appears on all matching clusters). Not adopted yet because:
- Migration cost is high (existing Applications would need recreation)
- ApplicationSet behavior on cluster removal requires careful finalizer design
- The current pattern is working and well-understood by the team
ApplicationSet remains a candidate for Phase 2.
### Alternative 3: Separate generic chart per team/BU
Rejected. The complexity of maintaining multiple templates outweighs the benefit of per-team customization. A single chart with cluster-level values is sufficient.
---
## References
- [SANCTITY_RULES.md R2](../../docs/global/SANCTITY_RULES.md) — the incubator ↔ values ↔ generic-chart contract is sacred
- [ADR-I1: Why one generic chart per cluster](ADR-I1-generic-chart-per-cluster.md) — companion ADR on the chart design
- [values-file-schema.md](../../docs/platform/schemas/values-file-schema.md) — full field reference
- [incubator-values-schema.md](../../docs/platform/schemas/incubator-values-schema.md) — incubator Application schema