VSO 시크릿 데이터 변환
VSO 시크릿 데이터 변환 (Secret transformation)
템플릿과 필터로 VSO가 소스 시크릿 데이터를 애플리케이션 호환 형식으로 변환하는 방법을 다룹니다.
출처: 문서
본문
고급 템플릿과 데이터 필터를 활용해, 쿠버네티스용 Vault Secrets Operator(VSO)는 소스 시크릿 데이터, 시크릿 메타데이터, 리소스 라벨·어노테이션을 애플리케이션에 호환되는 형식으로 변환할 수 있어요. 모든 시크릿 데이터 소스가 지원됩니다. 시크릿 변환은 시크릿 커스텀 리소스(CR) 안에 직접 지정하거나, 하나 이상의 SecretTransformation 커스텀 리소스 인스턴스를 참조하거나, 둘 다로 지정할 수 있어요.
템플릿 (Templating)
VSO는 데이터 중심의 Golang 템플릿을 사용해 시크릿 데이터 출력을 생성해요. 템플릿 데이터 입력에는 시크릿 데이터, 시크릿 메타데이터, 리소스 라벨·어노테이션이 들어 있어요.
템플릿은 시크릿 커스텀 리소스의 spec.Destination.Transformation.Templates 또는 SecretTransformation 리소스의 spec.templates에 구성됩니다.
VSO는 방대한 템플릿 함수 라이브러리에 대한 접근을 제공하며, 그 중 일부는 아래에 문서화되어 있어요.
시크릿 데이터 입력
시크릿 데이터는 .Secrets 입력 멤버로 접근해요. 이것은 시크릿 소스에서 가져온 민감 정보로 간주되는 시크릿 키-값 쌍의 맵을 담고 있습니다.
예를 들어 애플리케이션의 시크릿에 비밀번호를 포함하려면 다음과 같은 템플릿을 지정할 수 있어요.
{{- printf "password=%s" (get .Secrets "password") -}}
시크릿 메타데이터 입력
시크릿 메타데이터는 .Metadata 입력 멤버로 접근해요. 메타데이터 키를 값에 매핑하는 맵을 담고 있어요. 데이터는 기밀 정보를 담으면 안 됩니다.
예를 들어 애플리케이션의 시크릿에 시크릿 메타데이터 값을 포함하려면:
{{- printf "secretGroup=%s" (get .Metadata "secretGroup") -}}
리소스 어노테이션 입력
리소스 어노테이션은 .Annotations 입력 멤버로 접근해요. 어노테이션은 시크릿 커스텀 리소스에 구성된 모든 metadata.annotations로 구성됩니다.
예를 들어 애플리케이션의 시크릿에 리소스 어노테이션의 값을 포함하려면:
{{- printf "host=%s" (get .Annotations "myapp.config/host") -}}
리소스 라벨 입력
리소스 라벨은 .Labels 입력 멤버로 접근해요. 라벨은 시크릿 커스텀 리소스에 구성된 모든 metadata.labels로 구성됩니다.
예를 들어 애플리케이션의 시크릿에 리소스 라벨의 값을 포함하려면:
{{- printf "appType=%s" (get .Labels "appType") -}}
필터 (Filters)
필터는 대상 시크릿의 데이터에 어떤 소스 시크릿 데이터 필드가 포함되는지 제어하는 데 사용해요. 이들은 RE2가 허용하는 정규 표현식의 exclude/include 집합으로 지정됩니다.
필터는 시크릿 커스텀 리소스의 spec.Destination.Transformation의 excludes·includes 필드나, SecretTransformation 리소스의 spec에 구성됩니다.
모든 exclude 패턴은 include 패턴보다 우선하며, 템플릿화된 키에는 절대 적용되지 않아요.
예제 (Examples)
로컬 변환 (Local transformation)
Vault에서 example-vds라는 쿠버네티스 시크릿으로 Postgres 데이터베이스 자격 증명을 동기화하도록 구성된 VaultDynamicSecret.
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultDynamicSecret
metadata:
namespace: example-ns
name: example-vds
annotations:
myapp.config/postgres-host: postgres-postgresql.postgres.svc.cluster.local:5432
spec:
destination:
create: true
name: app-secret
transformation:
excludes:
- .*
templates:
url:
text: |
{{- $host := get .Annotations "myapp.config/postgres-host" -}}
{{- printf "postgresql://%s:***@%s/postgres?sslmode=disable" (get .Secrets "username") (get .Secrets "password") $host -}}
path: creds/dev-postgres
결과 쿠버네티스 시크릿에는 url이라는 단일 키가 값으로 유효한 Postgres 연결 URL과 함께 포함됩니다.
url: postgresql://v-postgres-user:***@postgres-postgresql.postgres.svc.cluster.local:5432/postgres?sslmode=disable
공유 변환 (Shared transformation)
다음 매니페스트에는 공유 변환 템플릿과 필터가 들어 있어요. 제공하는 모든 템플릿은 대상 k8s 시크릿에 포함됩니다. 또한 시크릿 CR이나 같은 리소스 인스턴스 안에 구성된 어떤 템플릿 텍스트에도 포함할 수 있는 sourceTemplates를 제공합니다.
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: SecretTransformation
metadata:
name: vso-templates
namespace: example-vds
spec:
excludes:
- password|username
templates:
url:
text: '{{- template "dbUrl" . -}}'
sourceTemplates:
- name: helpers
text: |
{{/*
create a Java props from SecretInput for this app
*/}}
{{- define "appProps" -}}
{{- $host := get .Annotations "myapp.config/postgres-host" -}}
{{- printf "db.host=%s\n" $host -}}
{{- range $k, $v := .Secrets -}}
{{- printf "db.%s=%s\n" $k $v -}}
{{- end -}}
{{- end -}}
{{/*
create a JSON config from SecretInput for this app
*/}}
{{- define "appJson" -}}
{{- $host := get .Annotations "myapp.config/postgres-host" -}}
{{- $copy := .Secrets | mustDeepCopy -}}
{{- $_ := set $copy "host" $host -}}
{{- mustToPrettyJson $copy -}}
{{- end -}}
{{/*
compose a Postgres URL from SecretInput for this app
*/}}
{{- define "dbUrl" -}}
{{- $host := get .Annotations "myapp.config/postgres-host" -}}
{{- printf "postgresql://%s:***@%s/postgres?sslmode=disable" (get .Secrets "username") (get .Secrets "password") $host -}}
{{- end -}}
{{/*
get the app name from the VSO resource's label
*/}}
{{- define "appName" -}}
{{- get .Labels "myapp/name" -}}
{{- end -}}
다음 VaultDynamicSecret 매니페스트는 위의 SecretTransformation을 참조해요. 참조 객체의 모든 템플릿과 필터가 대상 시크릿 데이터에 적용됩니다.
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultDynamicSecret
metadata:
namespace: example-ns
name: example-vds
annotations:
myapp.config/postgres-host: postgres-postgresql.postgres.svc.cluster.local:5432
spec:
destination:
create: true
name: app-secret
transformation:
transformationRefs:
- name: vso-templates
path: creds/dev-postgres
결과 쿠버네티스 시크릿에는 url이라는 단일 키가 값으로 유효한 Postgres 연결 URL과 함께 포함됩니다.
url: postgresql://v-postgres-user:***@postgres-postgresql.postgres.svc.cluster.local:5432/postgres?sslmode=disable
템플릿 함수 (Template functions)
모든 템플릿 함수는 sprig 라이브러리에서 제공돼요. 흔히 쓰는 함수 몇 가지를 아래에 언급합니다. 전체 함수 목록은 allowedSprigFuncs를 참고하세요.
문자열 함수
trim은 입력에서 앞·뒤 공백을 제거해요.
trim " host " -> `host`
인코딩 함수
b64enc는 입력 값을 base64로 인코딩해요.
b64enc "host" -> `aG9zdAo=`
b64dec는 입력 값을 base64로 디코딩해요.
b64dec "aG9zdAo=" -> `host`
맵 함수
get은 맵 입력에서 값을 가져와요.
get .Secrets "baz" -> `qux`
중첩 맵 입력이 주어지면:
{
"foo": {
"bar": "baz",
"quz": "quux"
}
}
get으로 특정 값을 가져올 수 있어요.
get (get .Secrets "foo") "bar" -> `baz`
dig로도 특정 값을 가져오거나, 키를 찾지 못하면 기본값을 반환할 수 있어요.
dig "foo" "quz" "" .Secrets -> `quux`
dig "foo" "nux" "" .Secrets -> ``