Scaling Argo CD with ApplicationSets: Stop Repeating Your Manifests
Stop duplicating Argo CD manifests. Use ApplicationSets to automate the creation of multiple Applications across dev, staging, and prod using a single template.
09 Aug 2026, 00:45 UTC

The Manifest Duplication Trap
Managing a handful of microservices across three environments is simple. Managing fifty microservices across dev, staging, and production is a maintenance nightmare. Without a templating mechanism, you end up with nearly identical Argo CD Application manifests that differ only by a namespace or a values file. This duplication leads to "configuration drift," where a critical update is applied to staging but forgotten in production because the manifests are managed as separate, disconnected files.
The ApplicationSet Solution
The ApplicationSet controller acts as a factory for Argo CD Applications. Instead of defining each Application individually, you define one ApplicationSet containing a generator and a template. The generator identifies the targets (such as a list of clusters or a set of Git folders), and the template defines how the resulting Applications should look. This ensures that every environment follows the exact same deployment pattern, with only the specific variables changing.
Worked Example: Multi-Environment Helm Deployments
The following configuration uses a list generator to deploy a single Helm chart to three distinct environments. This approach centralizes the logic while keeping environment-specific values isolated in separate files.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: backend-services-set
namespace: argocd
spec:
generators:
- list:
elements:
- env: dev
valuesFile: values-dev.yaml
targetNamespace: app-dev
- env: staging
valuesFile: values-staging.yaml
targetNamespace: app-staging
- env: prod
valuesFile: values-prod.yaml
targetNamespace: app-prod
template:
metadata:
name: '{{env}}-backend-api'
spec:
project: default
source:
repoURL: https://github.com/org/api-repo.git
targetRevision: HEAD
path: charts/api-service
helm:
valueFiles:
- '{{valuesFile}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{targetNamespace}}'
Execution and Verification:
1. Run kubectl apply -f appset.yaml using a cluster-admin account.
2. Verify the generated apps by running argocd app list. You should see dev-backend-api, staging-backend-api, and prod-backend-api.
3. Check the controller status: kubectl logs -n argocd -l app.kubernetes.io/name=applicationset-controller.
Operational Trade-offs and Limitations
While ApplicationSets reduce boilerplate, they introduce a layer of abstraction that can complicate debugging. When an Application fails to sync, you must first determine if the issue lies within the ApplicationSet controller (failure to generate the app) or within the generated Application itself (failure to deploy the resources).
Additionally, scaling to hundreds of Applications can put significant pressure on the Kubernetes API server. Because the controller constantly polls generators and updates Application objects, you may encounter API rate limiting. For very large fleets, consider sharding your ApplicationSets by business unit or service group rather than creating one massive global set.
Implementation Checklist
- Version Check: Run
argocd version. Ensure you are on v2.2 or newer, as ApplicationSet stability and core generators were solidified in this release. - Permission Audit: Ensure the Argo CD service account has the necessary RBAC permissions to create Application resources in the target namespace.
- Resource Monitoring: Monitor the memory and CPU usage of the
applicationset-controllerpod as you increase the number of elements in your generators. - Rollback Plan: To remove all generated applications, delete the
ApplicationSetobject. By default, this will also delete the child Applications it created.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.