on
Choosing between App-of-Apps and ApplicationSet for Argo CD GitOps
GitOps with Argo CD scales along two common patterns: the App-of-Apps (a root Application that manages child Application objects) and the ApplicationSet controller (a declarative template plus generators that produce many Applications automatically). Both solve the problem of “many applications, one control plane,” but they suit different teams and operational needs. This short guide compares the two patterns, shows concise examples, and points out practical trade-offs to help you pick the simplest fit.
Two patterns, one goal
-
App-of-Apps: a single Argo CD Application (the root) stores YAML manifests that are themselves Application resources. Argo CD watches the root and deploys the child Applications it contains. This is straightforward to reason about and easy to implement for small-to-moderate fleets. (argo-cd.readthedocs.io)
-
ApplicationSet: a custom resource that defines a single Application template plus one or more generators (Git, list, cluster, matrix, etc.). The ApplicationSet controller expands the template into many Argo CD Applications automatically, based on generator input (for example, one generated Application per Git folder or per cluster). This makes it simple to create large numbers of near-identical apps or to support multi-cluster environments. (argo-cd.readthedocs.io)
When each pattern makes sense
- Use App-of-Apps when:
- You manage a modest number (tens) of distinct Applications with unique manifests.
- You need explicit, hand-crafted Application manifests and clear ordering or custom inter-app relationships. App-of-Apps maps naturally to explicit dependency sequences. (get.octopus.com)
- Use ApplicationSet when:
- You need to generate Applications dynamically (e.g., one per Git subfolder, per cluster, or for ephemeral preview environments).
- You operate many similar apps or many clusters and want a single manifest that scales through generators rather than hand authoring hundreds of Application YAMLs. (opsiocloud.com)
Minimal examples
App-of-Apps (root Application that points at a repo folder containing child Application YAMLs)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
spec:
project: default
source:
repoURL: https://git.example/repo.git
path: argocd/root
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated: {}
The root’s repo path (argocd/root) contains child Application manifests (one file per child) that Argo CD will apply and manage. This pattern gives you explicit control over each child Application. (argo-cd.readthedocs.io)
ApplicationSet (generate one Application per Git folder)
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: apps-from-git
spec:
generators:
- git:
repoURL: https://git.example/repo.git
directories:
- path: apps/* # generate an Application for each folder under apps/
template:
metadata:
name: '-app'
spec:
project: default
source:
repoURL: https://git.example/repo.git
path: ''
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: ''
This single ApplicationSet creates many Argo CD Applications based on repo structure; it’s ideal for reproducible onboarding and multi-cluster templating. (argo-cd.readthedocs.io)
Practical trade-offs and gotchas
-
Ordering and dependencies: ApplicationSet excels at scale but does not express application deployment order or hard dependencies between generated Applications. When strict sequencing (deploy DB before app) or fine-grained dependency logic is required, App-of-Apps or a mix (ApplicationSets generating App-of-Apps structures) is often clearer. (get.octopus.com)
-
Ownership and team autonomy: ApplicationSet can shift CD ownership to application teams by letting them add a folder or repo entry and get a managed Application automatically; App-of-Apps tends to centralize control in the repo that contains the root Application. Choose the model that aligns with your team structure and RBAC. (opsiocloud.com)
-
Visibility and UI: Newer Argo CD releases include ApplicationSet views and a preview tab in the UI so operators can see what Applications an ApplicationSet will generate before they are created. That improves safety when you generate many applications from a template. (argo-cd.readthedocs.io)
-
Complexity vs. explicitness: App-of-Apps is low-tech and explicit—easy to audit because each child Application is a real resource in Git. ApplicationSet introduces templating and generators which reduce repetition at scale but add abstraction that teams must learn and document. Balance maintainability against repetition.
Short checklist for picking the simpler path
- Small number of unique apps, need explicit control or ordering → App-of-Apps. (argo-cd.readthedocs.io)
- Large, repetitive fleet or dynamic environments (per-cluster, per-branch preview) → ApplicationSet. (argo-cd.readthedocs.io)
- Mixed requirements (some static, some dynamic) → combine: use ApplicationSets to generate the bulk, and App-of-Apps where explicit ordering or special configuration is required. (burrell.tech)
Conclusion
Both patterns are part of the Argo CD toolkit and each makes GitOps simpler in different operational contexts. App-of-Apps gives explicit, easy-to-reason-about control for smaller fleets and ordered deployments; ApplicationSet offers templated scale and automation for large, repetitive or multi-cluster environments. The simplest solution is the one that matches your team’s scale and operational model: explicit manifests when you need control, templates when you need to avoid repetition. (argo-cd.readthedocs.io)