- Use the App-of-Apps pattern for bootstrapping: a single root Application points to a directory of child Application CRDs, allowing one `kubectl apply` to deploy everything
- Prefer ApplicationSets over App-of-Apps for dynamic, template-driven application generation — use Git Directory, List, or Cluster generators to create Applications automatically
- Keep Kubernetes manifests in a separate layer from ApplicationSet/Application definitions — developers should work with plain K8s resources without needing to understand ArgoCD internals
- For multi-cluster management, register remote clusters with `argocd cluster add` and use ApplicationSets with the Cluster generator to deploy the same app across all clusters
- Separate your repo structure into three layers: base manifests (Helm/Kustomize), Application/ApplicationSet definitions, and environment-specific configuration (values/overlays)
- Use the App-of-Apps pattern to bootstrap an entire cluster: a root Application deploys child Application CRDs from a directory, enabling full cluster provisioning from a single entry point
- Prefer ApplicationSets over hand-written Application CRDs when deploying the same app to multiple environments or clusters — they reduce duplication and prevent configuration drift
- Use the Git Directory generator to create one Application per directory: `directories: [{ path: "apps/*" }]` — adding a new app is just creating a new directory
- Use the Cluster generator with ApplicationSets to deploy platform services (monitoring, ingress, cert-manager) identically across all registered clusters automatically
- Use the Matrix generator to combine cluster and Git generators — deploy every app in every cluster with a single ApplicationSet definition
- Keep a three-layer repo structure: Level 1 (Kubernetes manifests — Helm charts or Kustomize bases), Level 2 (ApplicationSets wrapping manifests into ArgoCD apps), Level 3 (optional App-of-Apps for bootstrapping)
- Never template Application CRDs with Helm — use ApplicationSets for dynamic generation; Application specs should be static, declarative, and version-controlled
- For monorepo setups, use `manifest-generate-paths` annotations and ApplicationSet path filters to ensure only relevant apps are refreshed on changes
- Implement progressive environment promotion with separate targetRevision values per environment: `main` for dev, release tags for staging, and pinned SHAs for production
- Use the Pull Request generator to create temporary preview environments for each PR — automatically create and destroy Applications when PRs are opened and closed
- Design for cluster bootstrapping: a new cluster should reach full operational state by adding its credentials to ArgoCD and letting ApplicationSets auto-generate all required Applications