ArgoCD App of Apps pattern
Problem
The cluster runs 30–50 applications: ingress-nginx, cert-manager, prometheus, product apps. Each ArgoCD Application is created by hand with kubectl apply or Helm, syncing is opaque, and it's easy to forget one. Onboarding a new cluster turns into a checklist of 40 kubectl apply commands.
Solution
The Argo CD docs describe the app of apps pattern as: "declaratively specify one Argo CD app that consists only of other apps". One root Application points to a Git directory that holds the manifests of the other Applications. ArgoCD picks up the root, then the children, and the children pick up the workloads. The state of the whole cluster lives in one repository and is deployed with a single kubectl apply of the root manifest.
Example
Layout of the argocd-apps/ repo:
argocd-apps/
├── root.yaml # The single entry point
└── apps/
├── ingress-nginx.yaml
├── cert-manager.yaml
├── prometheus.yaml
└── app-product.yaml
root.yaml — the only manifest you apply by hand:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/acme/argocd-apps.git
targetRevision: HEAD
path: apps
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
apps/ingress-nginx.yaml — a typical child Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ingress-nginx
namespace: argocd
spec:
project: default
source:
chart: ingress-nginx
repoURL: https://kubernetes.github.io/ingress-nginx
targetRevision: 4.11.3
helm:
valueFiles: [values.yaml]
destination:
server: https://kubernetes.default.svc
namespace: ingress-nginx
syncPolicy:
automated: { prune: true, selfHeal: true }
syncOptions: [CreateNamespace=true]
Onboarding a new cluster is now:
kubectl apply -f root.yaml
# That's it. ArgoCD creates the remaining 40 applications itself.
When to use
- More than one cluster (staging + prod) and reproducibility matters.
- More than ten applications per cluster.
- The team wants to see cluster state in Git rather than via
kubectl get all.
Source
- ramitsurana/awesome-kubernetes — the GitOps section
- Argo CD docs — Cluster Bootstrapping
How to apply it yourself
- Create a separate
argocd-appsrepository (or a directory in the infra monorepo). - Move all existing Applications there.
- Write
root.yamlpointing to the directory with the children. - Apply the root by hand once.
- Make sure adding a new application = one PR to the repo, no manual
kubectl. After that — status Studied.