How does ArgoCD handle multi-cluster deployments with ApplicationSets?
Quick Answer
ArgoCD ApplicationSets use a templating controller that generates multiple Application resources from a single template combined with generators like list, cluster, Git directory, Git file, merge, or matrix generators, enabling scalable multi-cluster and multi-tenant deployments without duplicating Application definitions.
Detailed Answer
Think of ApplicationSets like a mail merge in a word processor. You write one template letter (the Application template) and provide a spreadsheet of recipients with their unique details (the generator producing parameters). The mail merge engine produces one personalized letter for each row in the spreadsheet. Similarly, the ApplicationSet controller takes one Application template and one or more generators, then produces a unique ArgoCD Application for each set of parameters the generator yields — one per cluster, one per environment, or one per microservice, depending on your strategy.
ApplicationSets are a Kubernetes custom resource managed by the ApplicationSet controller, which runs alongside the core ArgoCD components. The resource specification consists of two main sections: generators and a template. Generators produce a list of parameter sets — key-value pairs that get substituted into the template. ArgoCD ships with several built-in generators including the list generator for explicit enumeration, the cluster generator that discovers clusters registered in ArgoCD, the Git directory generator that scans a repository for subdirectories, the Git file generator that reads JSON or YAML parameter files from a repository, the pull request generator for ephemeral preview environments, and the matrix and merge generators for combining multiple generators together. Each generator yields rows of parameters, and for each row, the controller renders the template with those parameters substituted in, creating a distinct Application resource.
Internally, the ApplicationSet controller watches for ApplicationSet resources and runs a reconciliation loop separate from the main ArgoCD Application Controller. When it detects a new or modified ApplicationSet, it evaluates the generators to produce the parameter matrix, renders the template for each parameter set, and then creates, updates, or deletes the corresponding Application resources. The controller uses owner references to track which Applications belong to which ApplicationSet, enabling garbage collection when parameters are removed from a generator. The matrix generator deserves special attention because it computes the Cartesian product of two child generators — for example, combining a cluster generator with a Git directory generator to deploy every microservice to every cluster, producing N times M Applications from just two generators.
In production, ApplicationSets shine for platform teams managing dozens or hundreds of clusters. A common pattern is to use the cluster generator combined with labels to target specific cluster groups — for example, deploying the payments-api to all clusters labeled region=us-east and tier=production. Another powerful pattern uses the Git file generator where each cluster has a configuration file in a dedicated repository, and the file contains cluster-specific parameters like replica counts, resource limits, and feature flags. When a new cluster is provisioned and registered with ArgoCD, the cluster generator automatically picks it up and creates Applications for it without any manual intervention, achieving true zero-touch multi-cluster deployment at scale.
A significant gotcha with ApplicationSets is the deletion policy. By default, when an ApplicationSet is deleted, all generated Applications and their managed resources are also deleted — this cascading behavior can be catastrophic if someone accidentally deletes the ApplicationSet in Git. The preserveResourcesOnDeletion policy prevents this by keeping the Applications alive even after the ApplicationSet is removed. Another common pitfall is generator parameter conflicts when using the matrix generator; if both child generators produce a parameter with the same key, the second generator's value silently overwrites the first, leading to subtle deployment errors. Teams should also be cautious with the pull request generator in production clusters — without proper RBAC scoping the ApplicationSet to a sandboxed project, a malicious pull request could deploy arbitrary workloads to production namespaces.