Go 템플릿
Go 템플릿 (Go Template)
ApplicationSet에서 Go Text Template을 사용할 수 있게 해주는 기능이에요. 복잡한 템플릿 로직이 필요한 경우 기본 fasttemplate보다 강력해서, 조건·반복·함수 활용이 가능해져요.
출처: 문서
본문
소개 (Introduction)
ApplicationSet은 Go Text Template을 사용할 수 있어요. 이 기능을 활성화하려면 ApplicationSet 매니페스트에 goTemplate: true를 추가하세요.
기본 Go Text Template 함수에 더해 Sprig 함수 라이브러리(env, expandenv, getHostByName 제외)도 사용할 수 있어요.
추가 normalize 함수는 모든 문자열 파라미터를 유효한 DNS 이름으로 사용할 수 있게 만들어 줘요 — 유효하지 않은 문자를 하이픈으로 바꾸고 253자에서 자르는 방식이에요. Application 이름 같은 것에 파라미터를 안전하게 만들 때 유용해요.
또 다른 slugify 함수가 추가됐는데, 기본적으로 정리(sanitize)하고 스마트하게 자르며(단어를 2개로 자르지 않음) 몇 가지 인자를 받아요:
- 첫 번째 인자(제공되면)는 슬러그의 최대 길이를 지정하는 정수예요.
- 두 번째 인자(제공되면)는 스마트 절단이 활성화되었는지 나타내는 boolean이에요.
- 마지막 인자(제공되면)는 slugify할 입력 이름이에요.
사용 예시 (Usage example)
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: test-appset
spec:
...
template:
metadata:
name: 'hellos3-{{.name}}-{{ cat .branch | slugify 23 }}'
annotations:
label-1: '{{ cat .branch | slugify }}'
label-2: '{{ cat .branch | slugify 23 }}'
label-3: '{{ cat .branch | slugify 50 false }}'
text/template에서 정의된 옵션을 커스터마이즈하려면 ApplicationSet에 goTemplate: true 옆에 goTemplateOptions: ["opt1", "opt2", ...] 키를 추가하면 돼요. 글을 쓰는 시점에 유용한 옵션은 missingkey=error 하나뿐임에 유의하세요.
goTemplateOptions의 권장 설정은 ["missingkey=error"]인데, 이렇게 하면 템플릿이 정의되지 않은 값을 조회할 때 조용히 무시되는 대신 오류가 보고돼요. 현재는 하위 호환성 때문에 이것이 기본 동작이 아니에요.
동기 (Motivation)
Go Template은 Go 표준 문자열 템플릿이에요. 또한 복잡한 템플릿 로직을 허용한다는 점에서 fasttemplate(기본 템플릿 엔진)보다 더 강력해요.
제한사항 (Limitations)
Go 템플릿은 필드 단위로, 문자열 필드에만 적용돼요. Go 텍스트 템플릿으로 불가능한 몇 가지 예시:
-
boolean 필드 템플릿:
apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet spec: goTemplate: true goTemplateOptions: ["missingkey=error"] template: spec: source: helm: useCredentials: "{{.useCredentials}}" # This field may NOT be templated, because it is a boolean field. -
객체 필드 템플릿:
apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet spec: goTemplate: true goTemplateOptions: ["missingkey=error"] template: spec: syncPolicy: "{{.syncPolicy}}" # This field may NOT be templated, because it is an object field. -
필드 간 제어 키워드 사용:
apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet spec: goTemplate: true goTemplateOptions: ["missingkey=error"] template: spec: source: helm: parameters: # Each of these fields is evaluated as an independent template, so the first one will fail with an error. - name: "{{range .parameters}}" - name: "{{.name}}" value: "{{.value}}" - name: throw-away value: "{{end}}" -
Git generator를 사용할 때 템플릿화된
project필드에 대한 서명 확인은 지원되지 않아요.apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet spec: goTemplate: true template: spec: project: {{.project}}
마이그레이션 가이드 (Migration guide)
전역 (Globals)
모든 템플릿은 파라미터를 GoTemplate 문법으로 바꿔야 해요:
예시: {{ some.value }}는 {{ .some.value }}가 돼요.
Cluster Generators
Go 템플릿을 활성화하면 {{ .metadata }}가 객체가 돼요.
{{ metadata.labels.my-label }}는{{ index .metadata.labels "my-label" }}가 돼요{{ metadata.annotations.my/annotation }}는{{ index .metadata.annotations "my/annotation" }}가 돼요
Git Generators
Go 템플릿을 활성화하면 {{ .path }}가 객체가 돼요. 따라서 Git generators의 템플릿에 몇 가지 변경이 필요해요:
{{ path }}는{{ .path.path }}가 돼요{{ path.basename }}는{{ .path.basename }}가 돼요{{ path.basenameNormalized }}는{{ .path.basenameNormalized }}가 돼요{{ path.filename }}는{{ .path.filename }}가 돼요{{ path.filenameNormalized }}는{{ .path.filenameNormalized }}가 돼요{{ path[n] }}는{{ index .path.segments n }}가 돼요- 파일 generator에서 사용된다면
{{ values }}는{{ .values }}가 돼요
예시:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-addons
spec:
generators:
- git:
repoURL: https://github.com/argoproj/argo-cd.git
revision: HEAD
directories:
- path: applicationset/examples/git-generator-directory/cluster-addons/*
template:
metadata:
name: '{{path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/argoproj/argo-cd.git
targetRevision: HEAD
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{path.basename}}'
는 이렇게 됩니다:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-addons
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
generators:
- git:
repoURL: https://github.com/argoproj/argo-cd.git
revision: HEAD
directories:
- path: applicationset/examples/git-generator-directory/cluster-addons/*
template:
metadata:
name: '{{.path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/argoproj/argo-cd.git
targetRevision: HEAD
path: '{{.path.path}}'
destination:
server: https://kubernetes.default.svc
namespace: '{{.path.basename}}'
Sprig 함수를 사용해 path 변수를 수동으로 구성하는 것도 가능해요:
with goTemplate: false |
with goTemplate: true |
with goTemplate: true + Sprig |
|---|---|---|
{{path}} |
{{.path.path}} |
{{.path.path}} |
{{path.basename}} |
{{.path.basename}} |
{{base .path.path}} |
{{path.filename}} |
{{.path.filename}} |
{{.path.filename}} |
{{path.basenameNormalized}} |
{{.path.basenameNormalized}} |
{{normalize .path.path}} |
{{path.filenameNormalized}} |
{{.path.filenameNormalized}} |
{{normalize .path.filename}} |
{{path[N]}} |
- |
{{index .path.segments N}} |
사용 가능한 템플릿 함수 (Available template functions)
ApplicationSet 컨트롤러가 제공하는 것:
env,expandenv,getHostByName을 제외한 모든 sprig Go 템플릿 함수normalize: 다음 규칙을 준수하도록 입력을 정리해요:- 253자를 넘지 않음
- 소문자 영숫자,
-또는.만 포함 - 영숫자 문자로 시작하고 끝남
slugify: 소개 섹션에서 설명한 대로normalize처럼 정리하고 스마트하게 자름(단어를 2개로 자르지 않음).toYaml/fromYaml/fromYamlArrayhelm 같은 함수
예시 (Examples)
기본 Go 템플릿 사용 (Basic Go template usage)
이 예시는 기본 문자열 파라미터 치환을 보여줘요.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: guestbook
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
- cluster: finance-preprod
url: https://9.8.7.6
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
미설정 파라미터 폴백 (Fallbacks for unset parameters)
일부 generator에서는 특정 이름의 파라미터가 항상 채워지지 않을 수 있어요(예: values generator나 git files generator). 이런 경우 Go 템플릿을 사용해 폴백 값을 제공할 수 있어요.
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: guestbook
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
generators:
- list:
elements:
- cluster: engineering-dev
url: https://kubernetes.default.svc
- cluster: engineering-prod
url: https://kubernetes.default.svc
nameSuffix: -my-name-suffix
template:
metadata:
name: '{{.cluster}}{{dig "nameSuffix" "" .}}'
spec:
project: default
source:
repoURL: https://github.com/argoproj/argo-cd.git
targetRevision: HEAD
path: applicationset/examples/list-generator/guestbook/{{.cluster}}
destination:
server: '{{.url}}'
namespace: guestbook
이 ApplicationSet은 engineering-dev라는 Application과 engineering-prod-my-name-suffix라는 Application을 생성해요.
미설정 파라미터는 오류이므로 존재하지 않는 속성 조회는 피해야 해요. 대신 dig 같은 템플릿 함수를 사용해 기본값으로 조회하세요. 미설정 파라미터를 0으로 기본값 처리하고 싶다면 goTemplateOptions: ["missingkey=error"]를 제거하거나 goTemplateOptions: ["missingkey=invalid"]로 설정하면 돼요.