Skip to content

Split View: ArgoCD ApplicationSet 컨트롤러 심층 분석

|

ArgoCD ApplicationSet 컨트롤러 심층 분석

1. ApplicationSet 개요

ApplicationSet은 ArgoCD의 확장 컨트롤러로, 하나의 ApplicationSet 리소스에서 여러 ArgoCD Application을 자동으로 생성하고 관리합니다. 대규모 멀티클러스터, 멀티테넌트 환경에서 수백 개의 Application을 효율적으로 관리할 수 있습니다.

핵심 구성 요소

ApplicationSet Controller
    |
    +-- Generator: Application 목록 생성을 위한 데이터 소스
    |
    +-- Template: Application 리소스의 템플릿
    |
    +-- Sync Policy: Application 생성/삭제/업데이트 정책

ApplicationSet 기본 구조

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 유형 상세

List Generator

가장 단순한 Generator로, 정적 목록에서 파라미터를 생성합니다:

spec:
  generators:
    - list:
        elements:
          - cluster: staging
            url: https://staging.example.com
            revision: develop
          - cluster: production
            url: https://production.example.com
            revision: main

사용 사례: 소수의 명시적 환경을 관리할 때

Cluster Generator

ArgoCD에 등록된 클러스터를 기반으로 Application을 생성합니다:

spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: production
            region: ap-northeast-2

Cluster Generator의 파라미터:

파라미터설명
name클러스터 이름
server클러스터 API 서버 URL
metadata.labels클러스터에 설정된 레이블
metadata.annotations클러스터에 설정된 어노테이션

로컬 클러스터(in-cluster) 처리:

# 로컬 클러스터를 포함하려면 명시적으로 설정
spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: production
        # 값이 비어있는 셀렉터는 모든 클러스터 매칭 (로컬 포함)

Git Generator - Directory

Git 저장소의 디렉토리 구조를 스캔하여 Application을 생성합니다:

spec:
  generators:
    - git:
        repoURL: https://github.com/org/gitops-config.git
        revision: HEAD
        directories:
          - path: apps/*
          - path: apps/excluded-app
            exclude: true

생성되는 파라미터:

파라미터예시
pathapps/frontend
path.basenamefrontend
path[0]apps
path[1]frontend
path.basenameNormalizedfrontend (RFC 1123 호환)

디렉토리 구조 예시:

gitops-config/
  apps/
    frontend/
      kustomization.yaml
    backend/
      kustomization.yaml
    database/
      kustomization.yaml

각 디렉토리에 대해 별도의 Application이 자동 생성됩니다.

Git Generator - File

Git 저장소의 JSON/YAML 파일에서 파라미터를 읽어 Application을 생성합니다:

spec:
  generators:
    - git:
        repoURL: https://github.com/org/gitops-config.git
        revision: HEAD
        files:
          - path: 'clusters/*/config.json'

config.json 파일 예시:

{
  "cluster": {
    "name": "production-east",
    "server": "https://prod-east.example.com",
    "environment": "production",
    "region": "us-east-1"
  }
}

템플릿에서 중첩 필드 참조:

template:
  metadata:
    name: 'app-{{cluster.name}}'
  spec:
    destination:
      server: '{{cluster.server}}'

Matrix Generator

두 Generator를 결합하여 카테시안 곱(Cartesian Product)을 생성합니다:

spec:
  generators:
    - matrix:
        generators:
          # Generator 1: 클러스터 목록
          - clusters:
              selector:
                matchLabels:
                  env: production
          # Generator 2: 앱 디렉토리 목록
          - git:
              repoURL: https://github.com/org/apps.git
              revision: HEAD
              directories:
                - path: apps/*

결과 예시:

(cluster=prod-east, path=apps/frontend)
(cluster=prod-east, path=apps/backend)
(cluster=prod-west, path=apps/frontend)
(cluster=prod-west, path=apps/backend)

각 조합에 대해 Application이 생성됩니다.

Merge Generator

여러 Generator의 결과를 공통 키로 병합합니다:

spec:
  generators:
    - merge:
        mergeKeys:
          - server
        generators:
          # 기본 Generator: 모든 클러스터
          - clusters:
              values:
                replicas: '3'
                env: default
          # 오버라이드 Generator: 특정 클러스터 설정
          - list:
              elements:
                - server: https://production.example.com
                  values.replicas: '5'
                  values.env: production

server 키가 일치하는 항목에 대해 오버라이드 값이 적용됩니다.

PullRequest Generator

Git 호스팅 서비스의 PR을 감지하여 프리뷰 환경을 자동 생성합니다:

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 파라미터:

파라미터설명
numberPR 번호
branch소스 브랜치 이름
branch_slugURL 안전한 브랜치 이름
head_shaHEAD 커밋 SHA
head_short_sha짧은 HEAD SHA
labelsPR에 부여된 레이블

SCMProvider Generator

SCM(Source Code Management) 프로바이더에서 저장소를 자동 발견합니다:

spec:
  generators:
    - scmProvider:
        github:
          organization: myorg
          allBranches: false
        filters:
          - repositoryMatch: '^gitops-.*'
            pathsExist:
              - deploy/kustomization.yaml

지원 SCM 프로바이더:

  • GitHub
  • GitLab
  • Bitbucket Server
  • Azure DevOps
  • Gitea

3. 템플릿 렌더링 엔진

기본 템플릿 문법

ApplicationSet은 이중 중괄호 문법으로 파라미터를 참조합니다. 이 문법은 Generator가 제공하는 값으로 치환됩니다.

template:
  metadata:
    name: 'app-{{cluster}}-{{path.basename}}'
    labels:
      env: '{{values.env}}'
  spec:
    source:
      repoURL: '{{url}}'
      path: '{{path}}'
    destination:
      server: '{{server}}'
      namespace: '{{namespace}}'

Go 템플릿 모드

더 복잡한 로직이 필요한 경우 Go 템플릿을 사용할 수 있습니다:

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 }}'

Go 템플릿에서 사용 가능한 함수:

함수설명예시
lower소문자 변환{{ .name | lower }}
upper대문자 변환{{ .name | upper }}
normalizeRFC 1123 정규화{{ .name | normalize }}
toJsonJSON으로 변환{{ .data | toJson }}
default기본값 설정{{ .value | default "3" }}

fasttemplate vs Go 템플릿 비교

특성fasttemplate (기본)Go 템플릿
문법이중 중괄호 (변수 치환만)Go template 전체 문법
조건문불가가능 (if/else)
반복문불가가능 (range)
함수불가Sprig 함수 사용 가능
성능빠름상대적으로 느림
설정기본값goTemplate: true 필요

4. Progressive Sync (단계적 동기화)

Rolling Sync 전략

ApplicationSet은 여러 Application을 단계적으로 동기화하는 기능을 제공합니다:

spec:
  strategy:
    type: RollingSync
    rollingSync:
      steps:
        - matchExpressions:
            - key: env
              operator: In
              values:
                - staging
          maxUpdate: 100% # staging 환경 먼저 전부 업데이트
        - matchExpressions:
            - key: env
              operator: In
              values:
                - production
          maxUpdate: 25% # production은 25%씩 업데이트

Progressive Sync 동작 원리

Step 1: staging 레이블이 있는 모든 Application 동기화
  -> 모든 Application이 Healthy가 될 때까지 대기

Step 2: production 레이블이 있는 Application25%만 동기화
  -> Healthy 확인 후 다음 25% 진행
  -> 모든 production Application이 완료될 때까지 반복

maxUpdate 옵션

설명
100%매칭되는 모든 Application을 동시에 업데이트
25%매칭되는 Application의 25%만 업데이트
1한 번에 1개만 업데이트
0자동 업데이트 없음 (수동으로 진행)

5. Cluster Decision Resource

개요

Cluster Decision Resource는 외부 컨트롤러가 Application의 대상 클러스터를 결정하도록 위임하는 메커니즘입니다:

spec:
  generators:
    - clusterDecisionResource:
        configMapRef: my-placement-decision
        name: placement-decision
        requeueAfterSeconds: 180

사용 사례

  • Open Cluster Management (OCM)의 Placement Decision 연동
  • 커스텀 클러스터 선택 로직 구현
  • 외부 정책 엔진 기반의 클러스터 라우팅

6. Reconciliation Loop

ApplicationSet Controller의 Reconciliation

반복:
  1. 모든 ApplicationSet 리소스 감시 (Informer)
  2.ApplicationSet에 대해:
     a. Generator 실행하여 파라미터 집합 생성
     b. 템플릿을 렌더링하여 원하는 Application 목록 생성
     c. 현재 존재하는 Application 목록 조회
     d. 비교하여:
        - 새로 추가할 Application 생성
        - 변경된 Application 업데이트
        - 제거 대상 Application 삭제 (정책에 따라)
  3. requeueAfterSeconds 후 재실행

Requeue 메커니즘

spec:
  generators:
    - pullRequest:
        github:
          owner: myorg
          repo: myapp
        requeueAfterSeconds: 60 # 60초마다 PR 상태를 다시 확인

requeueAfterSeconds는 Generator의 데이터 소스가 변경되었는지 주기적으로 확인합니다. Webhook을 사용할 수 없는 경우에 특히 유용합니다.

Event-Driven Reconciliation

ApplicationSet Controller는 다음 이벤트에 반응하여 즉시 reconciliation을 수행합니다:

  • ApplicationSet 리소스 변경
  • ArgoCD 클러스터 Secret 변경
  • Git Webhook 수신 (Git Generator)

7. Application 생명주기 관리

생성 정책

spec:
  syncPolicy:
    preserveResourcesOnDeletion: false # ApplicationSet 삭제 시 Application도 삭제

업데이트 정책

ApplicationSet은 다음 상황에서 Application을 업데이트합니다:

  • Generator 파라미터가 변경된 경우
  • 템플릿이 변경된 경우
  • ApplicationSet 자체가 수정된 경우

삭제 정책

spec:
  syncPolicy:
    preserveResourcesOnDeletion: true # ApplicationSet 삭제해도 Application 유지
옵션동작
preserveResourcesOnDeletion: falseApplicationSet 삭제 시 모든 Application도 삭제
preserveResourcesOnDeletion: trueApplicationSet 삭제해도 Application은 유지

Orphan Application 처리

Generator가 더 이상 특정 Application을 생성하지 않으면:

  • 기본: 해당 Application을 삭제
  • preserveResourcesOnDeletion: true: Application 유지

8. 실전 패턴

멀티클러스터 배포

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 프리뷰 환경

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}}'
      annotations:
        preview-url: 'https://pr-{{number}}.preview.example.com'
    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

환경별 값 오버라이드 (Merge Generator)

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: app-with-overrides
  namespace: argocd
spec:
  generators:
    - merge:
        mergeKeys:
          - name
        generators:
          - clusters:
              values:
                replicas: '2'
                logLevel: info
          - list:
              elements:
                - name: production-cluster
                  values.replicas: '5'
                  values.logLevel: warn
  template:
    metadata:
      name: 'myapp-{{name}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/org/myapp.git
        targetRevision: HEAD
        path: deploy
        helm:
          parameters:
            - name: replicas
              value: '{{values.replicas}}'
            - name: logLevel
              value: '{{values.logLevel}}'
      destination:
        server: '{{server}}'
        namespace: myapp

9. 트러블슈팅

일반적인 문제와 해결

Application이 생성되지 않는 경우:

  • Generator의 selector가 올바른지 확인
  • Git 경로가 존재하는지 확인
  • ApplicationSet Controller 로그 확인

Application이 예상과 다르게 삭제되는 경우:

  • preserveResourcesOnDeletion 설정 확인
  • Generator의 출력이 변경되었는지 확인
  • ApplicationSet의 소유권 관리 확인

템플릿 렌더링 오류:

  • 파라미터 이름이 Generator 출력과 일치하는지 확인
  • Go 템플릿 사용 시 goTemplate: true 설정 확인
  • goTemplateOptions에서 missingkey 처리 방식 확인

디버깅 명령

# ApplicationSet 상태 확인
kubectl get applicationset -n argocd

# ApplicationSet 상세 정보 확인
kubectl describe applicationset my-appset -n argocd

# ApplicationSet Controller 로그 확인
kubectl logs -n argocd deployment/argocd-applicationset-controller

# 생성된 Application 확인
argocd app list

10. 정리

ApplicationSet Controller의 핵심 요소:

  1. Generator: 다양한 데이터 소스(클러스터, Git, PR, SCM)에서 파라미터 생성
  2. Matrix/Merge: Generator를 조합하여 복잡한 배포 토폴로지 구현
  3. Template Engine: fasttemplate 또는 Go 템플릿으로 Application 리소스 렌더링
  4. Progressive Sync: Rolling 업데이트 전략으로 안전한 대규모 배포
  5. Reconciliation: Event-driven + 주기적 polling으로 상태 동기화
  6. 생명주기 관리: 생성/업데이트/삭제 정책으로 Application 자동 관리

ApplicationSet을 효과적으로 활용하면 수백 개의 Application을 하나의 리소스로 관리할 수 있어, 대규모 GitOps 환경의 운영 복잡도를 크게 줄일 수 있습니다.

[ArgoCD] ApplicationSet Controller Deep Dive

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:

ParameterDescription
nameCluster name
serverCluster API server URL
metadata.labelsLabels set on the cluster
metadata.annotationsAnnotations 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:

ParameterExample
pathapps/frontend
path.basenamefrontend
path[0]apps
path[1]frontend
path.basenameNormalizedfrontend (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:

ParameterDescription
numberPR number
branchSource branch name
branch_slugURL-safe branch name
head_shaHEAD commit SHA
head_short_shaShort HEAD SHA
labelsLabels 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

Featurefasttemplate (default)Go Template
SyntaxDouble curly braces (variable substitution only)Full Go template syntax
ConditionalsNot possiblePossible (if/else)
LoopsNot possiblePossible (range)
FunctionsNot possibleSprig functions available
PerformanceFastRelatively slower
ConfigDefaultgoTemplate: 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

ValueDescription
100%Update all matching Applications simultaneously
25%Update only 25% of matching Applications
1Update only 1 at a time
0No 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
OptionBehavior
preserveResourcesOnDeletion: falseDelete all Applications when ApplicationSet is deleted
preserveResourcesOnDeletion: trueKeep 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:

  1. Generators: Produce parameters from diverse data sources (clusters, Git, PR, SCM)
  2. Matrix/Merge: Combine Generators for complex deployment topologies
  3. Template Engine: Render Application resources with fasttemplate or Go templates
  4. Progressive Sync: Safe large-scale deployments with rolling update strategies
  5. Reconciliation: Event-driven + periodic polling for state synchronization
  6. 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.