Argo CD Application Sets: Template-Driven Multi-Environment Sync
Application Sets let you generate multiple Argo CD Apps from one template and value list. This post covers configuration, a working example, and version-aware checks.
30 Mar 2026, 04:35 UTC

Argo CD Application Sets: Template-Driven Multi-Environment Sync
In a GitOps setup with dozens of environments development staging production across multiple clusters creating and syncing individual Argo CD Applications becomes repetitive and prone to drift. A single mislabeled namespace or forgotten cluster selector can leave an environment out of sync for hours and manually applying the same source path across ten apps is both tedious and error-prone.
Useful takeaway: Application Sets let you define one template and a list of values and Argo CD generates the corresponding Application objects automatically. Changes to the source repository propagate to all generated apps ensuring consistent state across environments without duplicate YAML definitions.
How Application Sets work
An Application Set consists of two primary blocks. The generators block produces a list of value sets while the template block defines how those values map to an Argo CD Application resource. The template uses Go template syntax wrapping variable parts in double curly braces such as cluster or namespace. The generator can draw from a static list a Kubernetes ConfigMap or an external command output. When the source repository changes the Application Set controller reconciles the desired generated apps against the current state in the Argo CD server creating or updating apps as needed. This design centralizes multi-environment configuration in a single resource reducing the chance of configuration drift between environments.
Concrete example
Here is a minimal ApplicationSet definition that generates three apps one per environment. The generators block uses a static list element specifying a cluster name and namespace for each target. The template then injects those values into the Applications metadata name source path and destination namespace so each generated app points to a unique cluster and namespace while sharing the same upstream Git repository.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: multi-environment-apps
spec:
generators:
- list:
elements:
- { cluster: "dev-cluster", namespace: "dev-env" }
- { cluster: "staging-cluster", namespace: "staging-env" }
- { cluster: "prod-cluster", namespace: "prod-env" }
template:
metadata:
name: "{{cluster}}-app-{{namespace}}"
spec:
project: default
source:
repoURL: "https://github.com/example/infra.git"
targetRevision: HEAD
path: "environments/{{cluster}}/{{namespace}}"
destination:
server: "https://kubernetes.default.svc"
namespace: "{{namespace}}"
syncPolicy:
automated:
prune: true
selfHeal: trueTo deploy run the apply command with appropriate permissions:
kubectl apply -f multi-environment-apps.yaml
The command should be executed from a context pointing to the cluster where Argo CD is installed and the user typically needs cluster-admin or at least argo cd application create permissions. After the resources are created verify the generated apps by listing them with the Argo CD CLI.
- Run
argocd app list --filter multi-environmentyou should see three apps named dev-cluster-app-dev-env staging-cluster-app-staging-env and prod-cluster-app-prod-env. If the names differ check that the templates metadata.name format matches the element keys exactly. - Inspect each apps details with
argocd app get dev-cluster-app-dev-envto confirm the source path destination namespace and automated sync policy are correct. The output should show the Git repository URL the environments/dev-cluster/dev-env path and the automated sync policy with prune and selfHeal enabled.
Version-aware sync behavior
Release notes indicate that the propagation of sync windows and health status may differ between Argo CD v5.x and v6.x. In v6.x the health of generated applications often reflects the parent Application Sets status more directly allowing a single health glance to cover the entire set. In v5.x health propagation was not unified across generated apps so you may need to check each generated app individually as the sets health does not automatically aggregate the children status. Practical verification: after deploying a new Application Set run argocd app list and confirm all expected names appear with Healthy or Progressing status. Then inspect the generated Application manifests in the Argo CD repo UI or via kubectl get application app-name -n argocd to review sync window configuration if needed. If you are on v5.x and expect aggregated health consider upgrading or configuring health checks per generated app.
Limitations and naming discipline
Research cautions that a source repository with a large number of application definitions may increase API server load during initial sync. Additionally overlapping application names across different Application Sets can lead to unexpected resource conflicts. Mitigation strategies include keeping the value list reasonable under 50 elements using a consistent naming prefix such as env- or cluster- and monitoring API server metrics if sync operations stall. If you observe delayed sync or resource errors reducing the generator list size or refactoring the template can alleviate pressure.
Next steps
Create an Application Set with a three-element value list for your target environments apply it and run argocd app list to confirm the generated names and statuses. Adjust the template or value list based on the output and refer to the official release notes for your installed Argo CD version when evaluating sync window or health status behavior. For larger deployments consider splitting Application Sets by product area to keep generator lists manageable and to isolate API server impact.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.