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

4.1 KiB
Raw Blame History

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