Skip to main content
The ApplicationSet controller automates the generation of Argo CD Applications, improving multi-cluster and multi-tenant support. It enables templating Applications from various sources and allows developers to independently create Applications without cluster-administrator intervention.

Overview

ApplicationSet is a Kubernetes Custom Resource that automatically generates Argo CD Applications based on defined generators and templates.
Be aware of the security implications before allowing developers to create Applications via ApplicationSets.

Basic ApplicationSet

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: guestbook
  namespace: argocd
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
    - list:
        elements:
          - cluster: engineering-dev
            url: https://1.2.3.4
          - cluster: engineering-prod
            url: https://2.4.6.8
  template:
    metadata:
      name: '{{.cluster}}-guestbook'
    spec:
      project: my-project
      source:
        repoURL: https://github.com/infra-team/cluster-deployments.git
        targetRevision: HEAD
        path: guestbook/{{.cluster}}
      destination:
        server: '{{.url}}'
        namespace: guestbook
This ApplicationSet generates multiple Applications (one per cluster) from a single resource definition.

Generators

Generators provide parameters that are rendered into the Application template. ApplicationSet supports multiple generator types:

List Generator

Provides a fixed list of parameters:
generators:
  - list:
      elements:
        - cluster: dev
          url: https://dev.example.com
          env: development
        - cluster: prod
          url: https://prod.example.com
          env: production

Cluster Generator

Automatically discovers clusters registered in Argo CD:
generators:
  - clusters:
      selector:
        matchLabels:
          environment: production
      values:
        revision: main

Git Generator

Generates Applications based on Git repository contents:
generators:
  - git:
      repoURL: https://github.com/org/repo.git
      revision: HEAD
      directories:
        - path: apps/*

SCM Provider Generator

Automatically discovers repositories from SCM providers (GitHub, GitLab, Bitbucket, etc.):
generators:
  - scmProvider:
      github:
        organization: myorg
        allBranches: false
      filters:
        - repositoryMatch: ^app-.*

Pull Request Generator

Creates temporary preview environments for pull requests:
generators:
  - pullRequest:
      github:
        owner: myorg
        repo: myrepo
        labels:
          - preview

Matrix Generator

Generates the cartesian product of two generators:
generators:
  - matrix:
      generators:
        - list:
            elements:
              - cluster: dev
              - cluster: prod
        - list:
            elements:
              - app: frontend
              - app: backend
# Produces: dev-frontend, dev-backend, prod-frontend, prod-backend

Merge Generator

Merges parameters from multiple generators:
generators:
  - merge:
      generators:
        - clusters:
            selector:
              matchLabels:
                type: production
        - list:
            elements:
              - cluster: special-cluster
                special: true
      mergeKeys:
        - server

Template Configuration

The template defines the Application structure:
template:
  metadata:
    name: '{{.name}}'
    labels:
      environment: '{{.environment}}'
    annotations:
      managed-by: applicationset
  spec:
    project: '{{.project}}'
    source:
      repoURL: '{{.repoUrl}}'
      targetRevision: '{{.revision}}'
      path: '{{.path}}'
    destination:
      server: '{{.server}}'
      namespace: '{{.namespace}}'
    syncPolicy:
      automated:
        prune: true
        selfHeal: true

Go Template Support

Enable Go templating for advanced use cases:
spec:
  goTemplate: true
  goTemplateOptions: ["missingkey=error"]
  generators:
    - list:
        elements:
          - name: app1
            replicas: 3
  template:
    metadata:
      name: '{{.name}}'
    spec:
      source:
        helm:
          parameters:
            - name: replicas
              value: '{{.replicas}}'

Sync Policy

Control how ApplicationSet manages generated Applications:
spec:
  syncPolicy:
    # Preserve Applications when ApplicationSet is deleted
    preserveResourcesOnDeletion: true
    
    # Control Application lifecycle
    applicationsSync: sync  # or create-only, create-update, create-delete
PolicyCreateUpdateDelete
create-only
create-update
create-delete
sync (default)

Progressive Sync (Rollout Strategy)

Deploy Applications in a controlled sequence:
spec:
  strategy:
    type: RollingSync
    rollingSync:
      steps:
        - matchExpressions:
            - key: environment
              operator: In
              values:
                - dev
          maxUpdate: 1
        - matchExpressions:
            - key: environment
              operator: In
              values:
                - staging
          maxUpdate: 2
        - matchExpressions:
            - key: environment
              operator: In
              values:
                - prod
          maxUpdate: 100%

Ignore Application Differences

Prevent ApplicationSet from overwriting certain Application fields:
spec:
  ignoreApplicationDifferences:
    - jsonPointers:
        - /spec/syncPolicy
      # Applies to all Applications
    - name: specific-app
      jqPathExpressions:
        - .spec.source.helm.parameters

Preserved Fields

Preserve annotations and labels on generated Applications:
spec:
  preservedFields:
    annotations:
      - notifications.argoproj.io/*
      - custom.annotation.io/*
    labels:
      - team
      - cost-center

Template Patch

Apply patches to the base template:
spec:
  template:
    # Base template
    spec:
      project: default
  templatePatch: |
    spec:
      project: '{{ .project }}'
      {{- if eq .environment "prod" }}
      syncPolicy:
        automated:
          prune: false
      {{- end }}

Selectors

Filter generator output using label selectors:
generators:
  - clusters:
      selector:
        matchLabels:
          environment: production
        matchExpressions:
          - key: region
            operator: In
            values:
              - us-east-1
              - us-west-2
  - list:
      elements:
        - name: app1
          labels:
            tier: frontend
        - name: app2
          labels:
            tier: backend
    selector:
      matchLabels:
        tier: frontend

Multi-Tenancy with ApplicationSets

ApplicationSets enable self-service application creation:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: team-apps
spec:
  generators:
    - git:
        repoURL: https://github.com/teams/team-repos.git
        revision: HEAD
        files:
          - path: "teams/*/config.json"
  template:
    metadata:
      name: '{{.team}}-{{.app}}'
    spec:
      project: '{{.team}}'
      source:
        repoURL: '{{.repo}}'
        targetRevision: '{{.branch}}'
        path: '{{.path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{.team}}-{{.environment}}'

Status and Conditions

ApplicationSet maintains status information:
status:
  conditions:
    - type: ResourcesUpToDate
      status: "True"
      reason: ApplicationSetUpToDate
      message: All generated Applications are up to date
  applicationStatus:
    - application: dev-frontend
      lastTransitionTime: "2024-01-15T10:30:00Z"
      status: Healthy
    - application: prod-backend
      lastTransitionTime: "2024-01-15T10:32:00Z"
      status: Progressing

Example Use Cases

Use the Cluster generator to deploy the same application to all clusters matching a label selector.
Use the Git directory generator to automatically create Applications for each directory in a repository.
Use the Pull Request generator to automatically create preview environments for each pull request.
Combine Git file generator with team configurations to allow teams to self-manage their applications.

Best Practices

Use specific generators

Choose the most appropriate generator for your use case to simplify configuration

Enable Go templates

Use goTemplate: true for advanced templating capabilities

Implement progressive sync

Use rollout strategies for production deployments

Set sync policies

Configure appropriate sync policies to control Application lifecycle

Next Steps

Learn about AppProjects for multi-tenancy and access control

Build docs developers (and LLMs) love