템플릿

템플릿 (Templates)

ApplicationSet spec의 템플릿 필드는 Argo CD Application 리소스를 생성하는 데 사용돼요. generator가 만든 파라미터를 템플릿 필드에 꽂아 넣어({{values}}) 구체적인 Application 리소스를 만들어요. ApplicationSet은 fasttemplate을 사용하지만 곧 Go Template으로 대체될 예정이에요.

출처: 문서

본문

ApplicationSet spec의 템플릿 필드는 Argo CD Application 리소스를 생성하는 데 사용돼요.

ApplicationSet은 fasttemplate을 사용하지만, 곧 Go Template으로 대체될 예정이에요.

템플릿 필드 (Template fields)

Argo CD Application은 generator의 파라미터와 템플릿의 필드를 결합해 만들어져요({{values}}). 그리고 그로부터 구체적인 Application 리소스가 생성·적용돼요.

다음은 Cluster generator의 템플릿 하위 필드예요.

# (...)
 template:
   metadata:
     name: '{{ .nameNormalized }}-guestbook'
   spec:
     source:
       repoURL: https://github.com/infra-team/cluster-deployments.git
       targetRevision: HEAD
       path: guestbook/{{ .nameNormalized }}
     destination:
       server: '{{ .server }}'
       namespace: guestbook

사용 가능한 모든 파라미터(.name, .nameNormalized 등)에 대한 자세한 내용은 Cluster Generator 문서를 참고하세요.

템플릿 하위 필드는 Argo CD Application 리소스의 spec에 직접 대응해요.

  • project — 사용 중인 Argo CD Project를 가리켜요(기본 Argo CD Project를 쓰려면 여기에 default를 사용할 수 있어요).
  • source — 원하는 Application 매니페스트를 추출할 Git 저장소를 정의해요.
    • repoURL: 저장소 URL(예: https://github.com/argoproj/argocd-example-apps.git)
    • targetRevision: 저장소의 revision(tag/branch/commit)(예: HEAD)
    • path: Kubernetes 매니페스트(그리고/또는 Helm, Kustomize, Jsonnet 리소스)가 있는 저장소 안의 경로
  • destination: 어느 Kubernetes 클러스터/네임스페이스에 배포할지 정의해요.
    • name: 배포 대상 (Argo CD 안의) 클러스터 이름
    • server: 클러스터의 API Server URL(예: https://kubernetes.default.svc)
    • namespace: source에서 매니페스트를 배포할 대상 네임스페이스(예: my-app-namespace)

참고:

  • ApplicationSet 컨트롤러가 사용하려면 참조되는 클러스터가 이미 Argo CD에 정의되어 있어야 해요.
  • name 또는 server하나만 지정해야 해요. 둘 다 지정하면 오류가 반환돼요.
  • git generator를 사용할 때 템플릿화된 project 필드에서는 Signature Verification이 동작하지 않아요.

템플릿의 metadata 필드는 Application의 name을 설정하거나 Application에 라벨·어노테이션을 추가하는 데도 사용할 수 있어요.

ApplicationSet spec은 기본적인 형태의 템플릿을 제공하지만, Kustomize, Helm, Jsonnet 같은 도구의 완전한 구성 관리 기능을 대체하려는 것은 아니에요.

Helm 차트의 일부로 ApplicationSet 리소스 배포하기 (Deploying ApplicationSet resources as part of a Helm chart)

ApplicationSet은 Helm과 같은 템플릿 표기({{}})를 사용해요. Helm이 차트 템플릿을 렌더링할 때, ApplicationSet 렌더링용 템플릿도 함께 처리해요. ApplicationSet 템플릿이 다음과 같은 함수를 사용하면:

    metadata:
      name: '{{ "guestbook" | normalize }}'

Helm은 function "normalize" not defined 같은 오류를 뱉어요. ApplicationSet 템플릿이 generator 파라미터를 사용하면:

    metadata:
      name: '{{.cluster}}-guestbook'

Helm은 조용히 .cluster를 빈 문자열로 바꿔요.

이런 오류를 피하려면 템플릿을 Helm 문자열 리터럴로 작성하세요. 예를 들어:

    metadata:
      name: '{{`{{ .cluster | normalize }}`}}-guestbook'

이것은 ApplicationSet 리소스를 배포할 때 Helm을 사용하는 경우에만 적용돼요.

Generator 템플릿 (Generator templates)

ApplicationSet 리소스의 .spec.template 안에 템플릿을 지정하는 것 외에도, generator 안에서도 템플릿을 지정할 수 있어요. 이것은 spec-레벨 템플릿의 값을 덮어쓰는(override) 데 유용해요.

generator의 template 필드는 spec의 템플릿 필드보다 우선해요.

  • 두 템플릿 모두에 같은 필드가 있으면 generator의 필드 값이 사용돼요.
  • 두 템플릿 중 하나의 필드에만 값이 있으면 그 값이 사용돼요.

Generator 템플릿은 외부 spec-레벨 템플릿 필드에 대한 패치로 생각할 수 있어요.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: guestbook
spec:
  generators:
  - list:
      elements:
        - cluster: engineering-dev
          url: https://kubernetes.default.svc
      template:
        metadata: {}
        spec:
          project: "default"
          source:
            targetRevision: HEAD
            repoURL: https://github.com/argoproj/argo-cd.git
            # New path value is generated here:
            path: 'applicationset/examples/template-override/{{ .nameNormalized }}-override'
          destination: {}

  template:
    metadata:
      name: '{{ .nameNormalized }}-guestbook'
    spec:
      project: "default"
      source:
        repoURL: https://github.com/argoproj/argo-cd.git
        targetRevision: HEAD
        # This 'default' value is not used: it is replaced by the generator's template path, above
        path: applicationset/examples/template-override/default
      destination:
        server: '{{ .server }}'
        namespace: guestbook

이 예시에서 ApplicationSet 컨트롤러는 .spec.template에 정의된 path 값이 아니라 List generator가 생성한 path를 사용해 Application 리소스를 생성해요.

템플릿 패치 (Template Patch)

템플릿은 문자열 타입에서만 사용할 수 있어요. 하지만 어떤 사용 사례는 다른 타입에도 템플릿을 적용해야 할 수 있어요.

예시:

  • 자동 sync 정책을 조건부로 설정.
  • prune boolean을 조건부로 true로 전환.
  • 목록에서 여러 helm value 파일 추가.

templatePatch 기능은 jsonyaml을 지원하는 고급 템플릿을 가능하게 해요.

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: guestbook
spec:
  goTemplate: true
  generators:
  - list:
      elements:
        - cluster: engineering-dev
          url: https://kubernetes.default.svc
          autoSync: true
          prune: true
          valueFiles:
            - values.large.yaml
            - values.debug.yaml
  template:
    metadata:
      name: '{{ .nameNormalized }}-deployment'
    spec:
      project: "default"
      source:
        repoURL: https://github.com/infra-team/cluster-deployments.git
        targetRevision: HEAD
        path: guestbook/{{ .nameNormalized }}
      destination:
        server: '{{ .server }}'
        namespace: guestbook
  templatePatch: |
    spec:
      source:
        helm:
          valueFiles:
          {{- range $valueFile := .valueFiles }}
            - {{ $valueFile }}
          {{- end }}
    {{- if .autoSync }}
      syncPolicy:
        automated:
          prune: {{ .prune }}
    {{- end }}

중요templatePatchgo templating이 활성화되었을 때만 동작해요. 즉 템플릿 패치가 동작하려면 spec 아래의 goTemplate 필드를 true로 설정해야 해요.

중요templatePatch는 템플릿에 임의의 변경을 적용할 수 있어요. 파라미터에 신뢰할 수 없는 사용자 입력이 포함되어 있으면 템플릿에 악의적인 변경이 주입될 수 있어요. templatePatch는 신뢰할 수 있는 입력에서만 사용하거나, 템플릿에서 사용하기 전에 입력을 조심스럽게 이스케이프하기를 권장해요. 입력을 toJson으로 파이프하면 예를 들어 사용자가 개행(새 줄)이 있는 문자열을 성공적으로 주입하는 것을 막는 데 도움이 돼요.

spec.project 필드는 templatePatch에서 지원되지 않아요. 프로젝트를 변경해야 한다면 template 필드의 spec.project 필드를 사용할 수 있어요.

중요templatePatch를 작성할 때 패치(patch)를 만드는 것이에요. 패치에 빈 spec: # nothing in here이 포함되면 기존 필드를 효과적으로 지워버려요. 이 동작의 예시는 #17040을 참고하세요.

더 알아보기 (Learn more)

  • GoTemplate — Go 템플릿 활성화·사용법.
  • Generator — 생성된 파라미터와 템플릿 결합.