- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 1. ApplicationSet Overview
- 2. Generator Types in Detail
- 3. Template Rendering Engine
- 4. Progressive Sync
- 5. Cluster Decision Resource
- 6. Reconciliation Loop
- 7. Application Lifecycle Management
- 8. Practical Patterns
- 9. Troubleshooting
- 10. Summary
1. ApplicationSet Overview
ApplicationSet is an ArgoCD extension controller that automatically creates and manages multiple ArgoCD Applications from a single ApplicationSet resource. It enables efficient management of hundreds of Applications in large-scale multi-cluster, multi-tenant environments.
Core Components
ApplicationSet Controller
|
+-- Generator: Data source for generating Application lists
|
+-- Template: Application resource template
|
+-- Sync Policy: Application create/delete/update policies
Basic ApplicationSet Structure
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-appset
namespace: argocd
spec:
generators:
- list:
elements:
- cluster: staging
url: https://staging.example.com
- cluster: production
url: https://production.example.com
template:
metadata:
name: 'myapp-{{cluster}}'
spec:
project: default
source:
repoURL: https://github.com/org/myapp.git
targetRevision: HEAD
path: 'overlays/{{cluster}}'
destination:
server: '{{url}}'
namespace: myapp
2. Generator Types in Detail
List Generator
The simplest Generator, producing parameters from a static list:
spec:
generators:
- list:
elements:
- cluster: staging
url: https://staging.example.com
revision: develop
- cluster: production
url: https://production.example.com
revision: main
Cluster Generator
Creates Applications based on clusters registered with ArgoCD:
spec:
generators:
- clusters:
selector:
matchLabels:
env: production
region: ap-northeast-2
Cluster Generator parameters:
| Parameter | Description |
|---|---|
| name | Cluster name |
| server | Cluster API server URL |
| metadata.labels | Labels set on the cluster |
| metadata.annotations | Annotations set on the cluster |
Git Generator - Directory
Scans the directory structure of a Git repository to create Applications:
spec:
generators:
- git:
repoURL: https://github.com/org/gitops-config.git
revision: HEAD
directories:
- path: apps/*
- path: apps/excluded-app
exclude: true
Generated parameters:
| Parameter | Example |
|---|---|
| path | apps/frontend |
| path.basename | frontend |
| path[0] | apps |
| path[1] | frontend |
| path.basenameNormalized | frontend (RFC 1123 compliant) |
Git Generator - File
Reads parameters from JSON/YAML files in a Git repository:
spec:
generators:
- git:
repoURL: https://github.com/org/gitops-config.git
revision: HEAD
files:
- path: 'clusters/*/config.json'
Example config.json:
{
"cluster": {
"name": "production-east",
"server": "https://prod-east.example.com",
"environment": "production",
"region": "us-east-1"
}
}
Referencing nested fields in templates:
template:
metadata:
name: 'app-{{cluster.name}}'
spec:
destination:
server: '{{cluster.server}}'
Matrix Generator
Combines two Generators to produce a Cartesian Product:
spec:
generators:
- matrix:
generators:
- clusters:
selector:
matchLabels:
env: production
- git:
repoURL: https://github.com/org/apps.git
revision: HEAD
directories:
- path: apps/*
Result example:
(cluster=prod-east, path=apps/frontend)
(cluster=prod-east, path=apps/backend)
(cluster=prod-west, path=apps/frontend)
(cluster=prod-west, path=apps/backend)
Merge Generator
Merges results from multiple Generators by a common key:
spec:
generators:
- merge:
mergeKeys:
- server
generators:
- clusters:
values:
replicas: '3'
env: default
- list:
elements:
- server: https://production.example.com
values.replicas: '5'
values.env: production
Override values are applied for items matching the server key.
PullRequest Generator
Detects PRs from Git hosting services to auto-create preview environments:
spec:
generators:
- pullRequest:
github:
owner: myorg
repo: myapp
labels:
- preview
requeueAfterSeconds: 60
template:
metadata:
name: 'preview-{{branch}}-{{number}}'
spec:
source:
repoURL: https://github.com/myorg/myapp.git
targetRevision: '{{head_sha}}'
path: deploy/preview
destination:
server: https://kubernetes.default.svc
namespace: 'preview-{{number}}'
PullRequest Generator parameters:
| Parameter | Description |
|---|---|
| number | PR number |
| branch | Source branch name |
| branch_slug | URL-safe branch name |
| head_sha | HEAD commit SHA |
| head_short_sha | Short HEAD SHA |
| labels | Labels on the PR |
SCMProvider Generator
Auto-discovers repositories from SCM (Source Code Management) providers:
spec:
generators:
- scmProvider:
github:
organization: myorg
allBranches: false
filters:
- repositoryMatch: '^gitops-.*'
pathsExist:
- deploy/kustomization.yaml
Supported SCM providers: GitHub, GitLab, Bitbucket Server, Azure DevOps, Gitea
3. Template Rendering Engine
Default Template Syntax
ApplicationSet uses double curly brace syntax for parameter references, substituted with values from Generators.
template:
metadata:
name: 'app-{{cluster}}-{{path.basename}}'
labels:
env: '{{values.env}}'
spec:
source:
repoURL: '{{url}}'
path: '{{path}}'
destination:
server: '{{server}}'
namespace: '{{namespace}}'
Go Template Mode
For more complex logic, Go templates can be used:
spec:
goTemplate: true
goTemplateOptions: ['missingkey=error']
template:
metadata:
name: 'app-{{ .cluster | lower }}'
spec:
source:
path: '{{ if eq .env "production" }}overlays/prod{{ else }}overlays/dev{{ end }}'
fasttemplate vs Go Template Comparison
| Feature | fasttemplate (default) | Go Template |
|---|---|---|
| Syntax | Double curly braces (variable substitution only) | Full Go template syntax |
| Conditionals | Not possible | Possible (if/else) |
| Loops | Not possible | Possible (range) |
| Functions | Not possible | Sprig functions available |
| Performance | Fast | Relatively slower |
| Config | Default | goTemplate: true required |
4. Progressive Sync
Rolling Sync Strategy
ApplicationSet provides progressive synchronization of multiple Applications:
spec:
strategy:
type: RollingSync
rollingSync:
steps:
- matchExpressions:
- key: env
operator: In
values:
- staging
maxUpdate: 100%
- matchExpressions:
- key: env
operator: In
values:
- production
maxUpdate: 25%
Progressive Sync Flow
Step 1: Sync all Applications with staging label
-> Wait until all are Healthy
Step 2: Sync only 25% of Applications with production label
-> Verify Healthy, proceed to next 25%
-> Repeat until all production Applications are complete
maxUpdate Options
| Value | Description |
|---|---|
| 100% | Update all matching Applications simultaneously |
| 25% | Update only 25% of matching Applications |
| 1 | Update only 1 at a time |
| 0 | No auto-update (manual progression) |
5. Cluster Decision Resource
External controllers can determine target clusters for Applications:
spec:
generators:
- clusterDecisionResource:
configMapRef: my-placement-decision
name: placement-decision
requeueAfterSeconds: 180
Use cases: Open Cluster Management (OCM) integration, custom cluster selection logic, external policy engine-based routing.
6. Reconciliation Loop
ApplicationSet Controller Reconciliation
Loop:
1. Watch all ApplicationSet resources (Informer)
2. For each ApplicationSet:
a. Execute Generator to produce parameter sets
b. Render template to produce desired Application list
c. Query existing Application list
d. Compare and:
- Create new Applications
- Update changed Applications
- Delete removed Applications (per policy)
3. Re-execute after requeueAfterSeconds
Requeue Mechanism
spec:
generators:
- pullRequest:
github:
owner: myorg
repo: myapp
requeueAfterSeconds: 60
Event-Driven Reconciliation
The controller responds immediately to:
- ApplicationSet resource changes
- ArgoCD cluster Secret changes
- Git Webhook receipt (Git Generator)
7. Application Lifecycle Management
Deletion Policy
spec:
syncPolicy:
preserveResourcesOnDeletion: true # Keep Applications when ApplicationSet is deleted
| Option | Behavior |
|---|---|
| preserveResourcesOnDeletion: false | Delete all Applications when ApplicationSet is deleted |
| preserveResourcesOnDeletion: true | Keep Applications even when ApplicationSet is deleted |
8. Practical Patterns
Multi-Cluster Deployment
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: platform-services
namespace: argocd
spec:
generators:
- matrix:
generators:
- clusters:
selector:
matchLabels:
tier: production
- git:
repoURL: https://github.com/org/platform.git
revision: HEAD
directories:
- path: services/*
template:
metadata:
name: '{{name}}-{{path.basename}}'
spec:
project: platform
source:
repoURL: https://github.com/org/platform.git
targetRevision: HEAD
path: '{{path}}'
destination:
server: '{{server}}'
namespace: '{{path.basename}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
PR Preview Environments
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: preview-envs
namespace: argocd
spec:
generators:
- pullRequest:
github:
owner: myorg
repo: myapp
labels:
- deploy-preview
requeueAfterSeconds: 30
template:
metadata:
name: 'preview-{{number}}'
spec:
project: previews
source:
repoURL: https://github.com/myorg/myapp.git
targetRevision: '{{head_sha}}'
path: deploy/preview
helm:
parameters:
- name: ingress.host
value: 'pr-{{number}}.preview.example.com'
- name: image.tag
value: '{{head_short_sha}}'
destination:
server: https://kubernetes.default.svc
namespace: 'preview-{{number}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
9. Troubleshooting
Common Issues
Applications not being created:
- Verify Generator selector is correct
- Verify Git paths exist
- Check ApplicationSet Controller logs
Applications unexpectedly deleted:
- Check preserveResourcesOnDeletion setting
- Verify if Generator output has changed
- Review ApplicationSet ownership management
Template rendering errors:
- Verify parameter names match Generator output
- Check goTemplate: true is set for Go templates
- Review goTemplateOptions for missingkey handling
Debugging Commands
# Check ApplicationSet status
kubectl get applicationset -n argocd
# View ApplicationSet details
kubectl describe applicationset my-appset -n argocd
# Check ApplicationSet Controller logs
kubectl logs -n argocd deployment/argocd-applicationset-controller
# List generated Applications
argocd app list
10. Summary
Key elements of the ApplicationSet Controller:
- Generators: Produce parameters from diverse data sources (clusters, Git, PR, SCM)
- Matrix/Merge: Combine Generators for complex deployment topologies
- Template Engine: Render Application resources with fasttemplate or Go templates
- Progressive Sync: Safe large-scale deployments with rolling update strategies
- Reconciliation: Event-driven + periodic polling for state synchronization
- Lifecycle Management: Automatic Application management with create/update/delete policies
Effective use of ApplicationSet enables managing hundreds of Applications from a single resource, dramatically reducing operational complexity in large-scale GitOps environments.