The Argo CD App of Apps pattern allows you to manage a large number of applications by defining a central "Application" resource that points to other "Application" resources, effectively creating a tree-like structure for your deployments.
Let’s see this in action. Imagine you have a cluster and you want to deploy a set of applications: a frontend, a backend, and a database. Instead of creating individual Argo CD Application resources for each, you create one "parent" application that manages these "child" applications.
Here’s the YAML for our parent Application resource, let’s call it app-of-apps.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: 'https://github.com/your-repo/argocd-app-of-apps.git'
targetRevision: HEAD
path: apps/
destination:
server: 'https://kubernetes.default.svc'
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
In this root-app definition:
repoURL: Points to the Git repository where your application definitions live.path: Specifies the directory (apps/) within that repository that contains the YAML files for your child applications.destination: Tells Argo CD where to deploy these applications – in this case, the default Kubernetes cluster and theargocdnamespace for the Argo CD controller itself.syncPolicy: Configures automated syncing, pruning, and self-healing for this parent application.
Now, inside the apps/ directory in your Git repository, you’d have the YAML definitions for your child applications. For example, frontend-app.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: frontend
namespace: argocd # Argo CD controller namespace
spec:
project: default
source:
repoURL: 'https://github.com/your-repo/frontend-app.git'
targetRevision: main
path: deploy/
destination:
server: 'https://kubernetes.default.svc'
namespace: frontend-prod # Namespace where the frontend app will run
syncPolicy:
automated:
prune: true
selfHeal: true
And backend-app.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: backend
namespace: argocd # Argo CD controller namespace
spec:
project: default
source:
repoURL: 'https://github.com/your-repo/backend-app.git'
targetRevision: main
path: k8s/
destination:
server: 'https://kubernetes.default.svc'
namespace: backend-prod # Namespace where the backend app will run
syncPolicy:
automated:
prune: true
selfHeal: true
When you apply root-app.yaml to your cluster using kubectl apply -f root-app.yaml, Argo CD will read it. It sees that this is an Application resource and that its source is a Git repository path. Argo CD then looks into the apps/ directory in your argocd-app-of-apps.git repository. It finds frontend-app.yaml and backend-app.yaml. Because these are also Application resources, Argo CD interprets them as applications to manage. It will then proceed to sync and deploy the frontend and backend applications according to their respective definitions.
The mental model here is a declarative dependency graph. The root-app doesn’t do anything itself; it declares that frontend and backend applications should exist. Argo CD’s controller then acts as the orchestrator, ensuring that these declared applications are reconciled with their desired state defined in their Git sources and targeting their specified Kubernetes namespaces. You can nest this pattern: a child application can itself be an "app of apps," managing further sub-applications. This allows for complex, hierarchical management of your entire application landscape from a single point of entry.
The beauty of this is that you can add a new application by simply adding a new Application YAML file to the apps/ directory in your Git repo and committing it. Argo CD will automatically detect and deploy it. This decouples the application deployment process from the Argo CD infrastructure itself.
What most people don’t realize is that the destination.namespace in the parent application (root-app in our example) is where Argo CD will deploy the child Application resources themselves. This is often argocd or a dedicated namespace for Argo CD’s own managed resources. The destination.namespace within the child applications is where the actual application workloads (Deployments, Services, etc.) will be deployed.
The next concept you’ll want to explore is how to manage the ordering and dependencies between these applications, which often leads to exploring Argo CD’s ApplicationSet for more advanced templating and lifecycle management.