As your platform grows you’ll find yourself creating a lot of very similar Applications — one per environment, one per team, one per cluster. Copy-pasting Application YAML quickly becomes error-prone. ApplicationSet is the ArgoCD controller that generates Applications automatically from a template and a set of parameters.
The idea: generator + template
An ApplicationSet has two parts:
- generators — produce a list of parameter sets (for example, one entry per environment or per cluster).
- template — an Application blueprint with
{{ }}placeholders that the generator fills in.
The controller renders one Application per generated parameter set and keeps them in sync. Delete an entry and the corresponding Application is removed; add one and a new Application appears.
List generator
The simplest generator is a hard-coded list. Here we create one Book Info Application per environment:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: book-info
namespace: argocd
spec:
goTemplate: true
generators:
- list:
elements:
- env: dev
namespace: book-info-dev
- env: prod
namespace: book-info-prod
template:
metadata:
name: 'book-info-{{ .env }}'
spec:
project: default
source:
repoURL: 'https://github.com/VersusControl/devops-vn-blog'
targetRevision: HEAD
path: '_resource/argocd-series/06-kustomize/book-info/overlays/{{ .env }}'
destination:
server: 'https://kubernetes.default.svc'
namespace: '{{ .namespace }}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Apply it and ArgoCD creates book-info-dev and book-info-prod for you — from a single
resource.
kubectl apply -f book-info-appset.yaml
Git directory generator
Even better, we can let the repository layout drive the Applications. The Git generator scans a repo and produces one parameter set per matching directory. Add a new folder to Git and a new Application appears automatically — no edits to the ApplicationSet.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: apps
namespace: argocd
spec:
goTemplate: true
generators:
- git:
repoURL: 'https://github.com/VersusControl/devops-vn-blog'
revision: HEAD
directories:
- path: 'apps/*'
template:
metadata:
name: '{{ .path.basename }}'
spec:
project: default
source:
repoURL: 'https://github.com/VersusControl/devops-vn-blog'
targetRevision: HEAD
path: '{{ .path.path }}'
destination:
server: 'https://kubernetes.default.svc'
namespace: '{{ .path.basename }}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
With a repo like:
apps/
├── productpage/
├── reviews/
└── ratings/
you get three Applications named productpage, reviews, and ratings. This “app of
apps, generated” pattern is one of the most popular uses of ApplicationSet.
Other generators
ApplicationSet ships with several generators you can mix and match:
- List — an explicit list of parameters (shown above).
- Cluster — one Application per cluster registered in ArgoCD (we’ll use this in the next post for multi-cluster).
- Git (directories / files) — driven by folders or config files in a repo.
- SCM Provider — one Application per repository in a GitHub/GitLab org.
- Pull Request — one Application per open PR, ideal for preview environments.
- Matrix — the cross-product of two generators (e.g. every app × every cluster).
- Merge — combine generators, letting later ones override earlier values.
Matrix: apps across environments
Say you want every app deployed to every environment. A matrix generator combines a Git
directory generator (the apps) with a list generator (the environments):
generators:
- matrix:
generators:
- git:
repoURL: 'https://github.com/VersusControl/devops-vn-blog'
revision: HEAD
directories:
- path: 'apps/*'
- list:
elements:
- env: dev
- env: prod
The template then has access to both {{ .path.basename }} and {{ .env }}, producing an
Application for each app/environment pair.
A safety note
Because an ApplicationSet can create and delete many Applications at once, enable it carefully. During rollout you can set:
spec:
syncPolicy:
applicationsSync: create-update # don't let it delete Applications yet
Once you trust it, switch to the default so removed entries are pruned.
The examples live in 09-applicationset.
ApplicationSet turns dozens of near-identical Applications into a single declarative resource. In the next post we’ll use its Cluster generator to deploy across many clusters — welcome to Multi-Cluster Deployments.