Setup ArgoCD ApplicationSets for multi-environment GitOps workflows with automated deployment pipelines

Advanced 45 min Jun 10, 2026 19 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure ArgoCD ApplicationSets to automate deployments across multiple environments using GitOps patterns. Learn to create templates, generators, and automated promotion workflows for production-grade Kubernetes deployments.

Prerequisites

  • Running Kubernetes cluster with kubectl access
  • ArgoCD installed or cluster-admin privileges
  • Git repository for storing application configurations
  • Basic understanding of Kubernetes manifests and Helm

What this solves

ArgoCD ApplicationSets automate the deployment of applications across multiple environments, clusters, or namespaces using template-based configurations. Instead of manually creating individual ArgoCD Applications for dev, staging, and production environments, ApplicationSets use generators to dynamically create and manage these applications from a single configuration.

Prerequisites

Requirements: You need a running Kubernetes cluster with ArgoCD already installed. This tutorial assumes you have cluster-admin privileges and kubectl configured.

Install ArgoCD if not already present

Skip this step if ArgoCD is already running in your cluster. Otherwise, install ArgoCD in the argocd namespace.

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Wait for ArgoCD components to be ready

Verify all ArgoCD components are running before proceeding with ApplicationSet configuration.

kubectl wait --for=condition=ready pod -l app.kubernetes.io/part-of=argocd -n argocd --timeout=300s

Install ArgoCD ApplicationSet Controller

The ApplicationSet controller is included in recent ArgoCD versions but may need explicit installation on older versions.

kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/applicationset/v0.4.1/manifests/install.yaml

Step-by-step configuration

Create Git repository structure

Set up a proper GitOps repository structure to support multi-environment deployments with ApplicationSets.

mkdir -p gitops-demo/{apps,environments/{dev,staging,prod},clusters}
cd gitops-demo

Create base application manifests

Create a base application configuration that will be templated across environments.

apiVersion: v1
kind: Namespace
metadata:
  name: nginx-{{.environment}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: nginx-{{.environment}}
spec:
  replicas: {{.replicas}}
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        environment: {{.environment}}
    spec:
      containers:
      - name: nginx
        image: nginx:{{.version}}
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: {{.cpu_request}}
            memory: {{.memory_request}}
          limits:
            cpu: {{.cpu_limit}}
            memory: {{.memory_limit}}
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: nginx-{{.environment}}
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP

Create environment-specific configurations

Define different resource allocations and configurations for each environment.

{
  "environment": "dev",
  "replicas": 1,
  "version": "1.21",
  "cpu_request": "100m",
  "memory_request": "128Mi",
  "cpu_limit": "200m",
  "memory_limit": "256Mi",
  "cluster": "dev-cluster",
  "namespace": "nginx-dev"
}

Create staging environment configuration

Configure staging with higher resource allocation and stable image versions.

{
  "environment": "staging",
  "replicas": 2,
  "version": "1.21",
  "cpu_request": "200m",
  "memory_request": "256Mi",
  "cpu_limit": "500m",
  "memory_limit": "512Mi",
  "cluster": "staging-cluster",
  "namespace": "nginx-staging"
}

Create production environment configuration

Configure production with high availability and resource allocation suitable for production workloads.

{
  "environment": "prod",
  "replicas": 3,
  "version": "1.20",
  "cpu_request": "500m",
  "memory_request": "512Mi",
  "cpu_limit": "1000m",
  "memory_limit": "1Gi",
  "cluster": "prod-cluster",
  "namespace": "nginx-prod"
}

Create cluster configuration files

Define cluster-specific settings that ApplicationSets can reference for multi-cluster deployments.

apiVersion: v1
kind: Secret
metadata:
  name: dev-cluster-secret
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
  name: dev-cluster
  server: https://dev.example.com
  config: |
    {
      "bearerToken": "",
      "tlsClientConfig": {
        "insecure": false
      }
    }

Create Git generator ApplicationSet

Create an ApplicationSet that uses Git file generator to automatically discover environments from your repository structure.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: nginx-environments
  namespace: argocd
spec:
  generators:
  - git:
      repoURL: https://github.com/your-org/gitops-demo
      revision: HEAD
      files:
      - path: "environments/*/config.json"
  template:
    metadata:
      name: 'nginx-{{environment}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/your-org/gitops-demo
        targetRevision: HEAD
        path: apps
        helm:
          valueFiles:
          - "../environments/{{environment}}/config.json"
      destination:
        server: https://kubernetes.default.svc
        namespace: 'nginx-{{environment}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
        - CreateNamespace=true

Create list generator ApplicationSet for specific clusters

Use list generator when you need explicit control over which clusters and environments to deploy to.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: nginx-multi-cluster
  namespace: argocd
spec:
  generators:
  - list:
      elements:
      - cluster: dev-cluster
        url: https://dev.example.com
        environment: dev
        replicas: "1"
        version: "1.21"
      - cluster: staging-cluster
        url: https://staging.example.com
        environment: staging
        replicas: "2"
        version: "1.21"
      - cluster: prod-cluster
        url: https://prod.example.com
        environment: prod
        replicas: "3"
        version: "1.20"
  template:
    metadata:
      name: 'nginx-{{environment}}-{{cluster}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/your-org/gitops-demo
        targetRevision: HEAD
        path: apps
        helm:
          parameters:
          - name: environment
            value: '{{environment}}'
          - name: replicas
            value: '{{replicas}}'
          - name: version
            value: '{{version}}'
      destination:
        server: '{{url}}'
        namespace: 'nginx-{{environment}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
        - CreateNamespace=true

Create cluster generator ApplicationSet

Automatically discover registered clusters and deploy applications to all of them.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: nginx-all-clusters
  namespace: argocd
spec:
  generators:
  - clusters:
      selector:
        matchLabels:
          environment: production
  template:
    metadata:
      name: 'nginx-{{name}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/your-org/gitops-demo
        targetRevision: HEAD
        path: apps
        helm:
          parameters:
          - name: environment
            value: '{{metadata.labels.environment}}'
          - name: cluster
            value: '{{name}}'
      destination:
        server: '{{server}}'
        namespace: nginx
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
        - CreateNamespace=true

Apply ApplicationSet configurations

Deploy the ApplicationSets to your cluster and verify they create the expected Application resources.

kubectl apply -f applicationset-git-generator.yaml
kubectl apply -f applicationset-list-generator.yaml

Configure RBAC for ApplicationSets

Set up proper permissions for ApplicationSet controller to manage applications across namespaces.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: applicationset-controller
rules:
  • apiGroups: ["argoproj.io"]
resources: ["applications", "applicationsets"] verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
  • apiGroups: [""]
resources: ["events"] verbs: ["create", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: applicationset-controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: applicationset-controller subjects:
  • kind: ServiceAccount
name: applicationset-controller namespace: argocd

Apply RBAC configuration

Apply the RBAC rules to ensure ApplicationSet controller has necessary permissions.

kubectl apply -f applicationset-rbac.yaml

Create progressive deployment ApplicationSet

Implement automated promotion workflow where successful deployment to dev triggers staging deployment.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: nginx-progressive
  namespace: argocd
spec:
  generators:
  - git:
      repoURL: https://github.com/your-org/gitops-demo
      revision: HEAD
      files:
      - path: "environments/*/config.json"
  template:
    metadata:
      name: 'nginx-{{environment}}'
      annotations:
        argocd-image-updater.argoproj.io/image-list: nginx=nginx
        argocd-image-updater.argoproj.io/write-back-method: git
    spec:
      project: default
      source:
        repoURL: https://github.com/your-org/gitops-demo
        targetRevision: HEAD
        path: apps
      destination:
        server: https://kubernetes.default.svc
        namespace: 'nginx-{{environment}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
        - CreateNamespace=true
      syncWindows:
      - kind: allow
        schedule: '0 2   *'
        duration: 1h
        applications:
        - 'nginx-prod'

Advanced ApplicationSet patterns

Create matrix generator for complex scenarios

Use matrix generator to combine multiple generators for complex deployment scenarios.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: nginx-matrix
  namespace: argocd
spec:
  generators:
  - matrix:
      generators:
      - git:
          repoURL: https://github.com/your-org/gitops-demo
          revision: HEAD
          directories:
          - path: environments/*
      - clusters:
          selector:
            matchLabels:
              environment: '{{path.basename}}'
  template:
    metadata:
      name: 'nginx-{{path.basename}}-{{name}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/your-org/gitops-demo
        targetRevision: HEAD
        path: apps
        helm:
          parameters:
          - name: environment
            value: '{{path.basename}}'
          - name: cluster
            value: '{{name}}'
      destination:
        server: '{{server}}'
        namespace: 'nginx-{{path.basename}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

Configure ApplicationSet with Helm chart source

Use ApplicationSets with Helm charts for more complex application packaging and configuration.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: nginx-helm
  namespace: argocd
spec:
  generators:
  - list:
      elements:
      - environment: dev
        values: |
          replicaCount: 1
          image:
            tag: "1.21"
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
      - environment: prod
        values: |
          replicaCount: 3
          image:
            tag: "1.20"
          resources:
            requests:
              cpu: 500m
              memory: 512Mi
  template:
    metadata:
      name: 'nginx-helm-{{environment}}'
    spec:
      project: default
      source:
        repoURL: https://charts.bitnami.com/bitnami
        chart: nginx
        targetRevision: 13.2.23
        helm:
          values: '{{values}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: 'nginx-{{environment}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
        - CreateNamespace=true

Monitoring and troubleshooting

Set up ApplicationSet monitoring

Create ServiceMonitor for Prometheus to scrape ApplicationSet controller metrics.

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: applicationset-controller-metrics
  namespace: argocd
spec:
  selector:
    matchLabels:
      app.kubernetes.io/component: applicationset-controller
      app.kubernetes.io/name: argocd-applicationset-controller
  endpoints:
  - port: metrics

Configure logging for ApplicationSet controller

Increase log level for debugging ApplicationSet issues and generator behavior.

kubectl patch deployment argocd-applicationset-controller -n argocd -p '{
  "spec": {
    "template": {
      "spec": {
        "containers": [{
          "name": "applicationset-controller",
          "args": [
            "--logLevel", "debug",
            "--metrics-addr", "0.0.0.0:8080"
          ]
        }]
      }
    }
  }
}'

Verify your setup

Check that ApplicationSets are creating the expected Applications and that they sync successfully.

# Check ApplicationSet status
kubectl get applicationsets -n argocd

Verify generated Applications

kubectl get applications -n argocd

Check ApplicationSet controller logs

kubectl logs -n argocd deployment/argocd-applicationset-controller

Verify applications are synced

kubectl get applications -n argocd -o jsonpath='{range .items[*]}{.metadata.name}: {.status.sync.status}{"\n"}{end}'

You can also check the ArgoCD UI to see the ApplicationSet and its generated Applications visually.

Common issues

Symptom Cause Fix
Applications not created Generator not finding files/clusters Check generator paths and cluster labels with kubectl describe applicationset
Template parameters not resolved Missing or incorrect generator field references Verify generator output fields match template variables
ApplicationSet controller crashloop RBAC permissions missing Apply comprehensive RBAC rules with cluster-admin if needed for testing
Git generator not detecting changes Repository access issues or path mismatch Check repository credentials and file paths in git generator
Applications stuck in sync Resource conflicts or namespace issues Check Application events and sync policy configuration
Cluster generator empty results No clusters match selector labels Verify cluster secrets have correct labels in argocd namespace

Next steps

Running this in production?

Want this handled for you? Running this at scale adds a second layer of work: capacity planning, failover drills, cost control, and on-call. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.