GenesisSecret スキーマ
GenesisSecret は、外部の Secret ストア(現バージョンでは 1Password)にある秘匿情報を取得し、 Kubernetes Secret として 生成 するための宣言です。
GenesisSecret は Kubernetes の CRD ではなく、Tazuna が読む YAML スキーマ です。
クラスタに GenesisSecret リソースが現れるわけではなく、適用結果として Secret が現れます。
tazuna.yaml からは type: genesissecret の Manifest として参照します。
# tazuna.yaml
spec:
manifests:
- name: aws-credentials
type: genesissecret
path: ./genesissecrets/aws.yaml
type: genesissecret の path は YAML ファイル 1 つを直接指します
(他の Manifest type のようにディレクトリを指すのではありません)。
ルート (GenesisSecret)
| フィールド | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
apiVersion | string | - | - | スキーマバージョンを示します。値は現状検証されません。 |
kind | string | - | - | リソース種別を示します。値は現状検証されません。 |
spec | GenesisSecretSpec | ◯ | - | GenesisSecret 本体。 |
apiVersion / kind のフィールドは構造体に対応する宣言がなく、書いても
読まれずに無視されますが、慣習として apiVersion: tazuna.pepabo.com/v1 /
kind: GenesisSecret を書いておくと、後から検証が入っても揃えやすくなります。
GenesisSecretSpec
| フィールド | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
provider | string | - | "" | 取得元 Provider の指定。現バージョンの Manager は値を参照していません。 Provider は Tazuna 全体で 1 つ(1Password 向け実装)が組み込まれていて、tazuna apply の起動時に決定されます。 |
secrets | [GenesisSecretGenerate] | ◯ | - | 取得対象。複数書けます。 |
outputs | [GenesisSecretOutput] | ◯ | - | 出力先。複数書けます。 |
GenesisSecretGenerate
secrets[] の各要素です。1 つの「Provider 上のアイテム」を表します。
| フィールド | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
uri | string | ◯ | - | Provider 上のアイテムを指す URI。詳細は uri の形式 参照。 |
items | map<string, GenesisSecretGenerateItem> | ◯ | - | Provider から取得した key と、出力 Secret 上のキー名の対応表。 |
preferLabel | bool | - | false | Provider が返したフィールドを ラベル名 でキー化するかどうか。false のときは ID(ランダム文字列になる場合がある)でキー化されます。1Password で人間が付けたフィールド名を items のキーに書きたい場合は true にします。 |
uri の形式
1Password Provider では、url.Parse の結果のうち path の 1 つ目を vault 名、2 つ目を item 名
として解釈します。scheme やホストは現バージョンでは使われません。
tazuna secret-to-genesissecret が自動生成するときは次の形式で書き出します。
op://<op-host>/<vault>/<item>
例:
uri: op://example.1password.com/Platform/aws-credentials
scheme やホストはパースには通りますが、参照されません。 将来別 Provider を増やしたときに使い分けるためのスペースとして残されている、と理解しておくと安全です。
GenesisSecretGenerateItem
items マップの 値 にあたる構造です(キーは Provider から返ってきた field の ID または label)。
| フィールド | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
mapTo | string | ◯ | - | 出力先 Kubernetes Secret の data キー名。Provider から取得した値はこのキー名で Secret に格納されます。 |
例:
items:
accessKeyID:
mapTo: AWS_ACCESS_KEY_ID
secretAccessKey:
mapTo: AWS_SECRET_ACCESS_KEY
items のキー accessKeyID が Provider 上のフィールド名(preferLabel: true ならラベル名)に対応し、
mapTo がそのまま Kubernetes Secret のキー名になります。
items のキーが Provider 側に存在しないとエラーになります。
GenesisSecretOutput
outputs[] の各要素です。1 つの「出力先」を表します。
| フィールド | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
kubernetesSecret | GenesisSecretOutputKubernetesSecret | △ (※) | null | 出力先として Kubernetes Secret を作る場合に指定します。 |
stdout | object | - | null | スキーマ上は存在しますが 現バージョンでは未対応 です。kubernetesSecret が null の場合は実行時にエラーになります。 |
(※) 現バージョンでは outputs[] の各要素は kubernetesSecret を必須 とします。
構造体上は stdout も存在しますが、kubernetesSecret == nil だと
.spec.output currently supports only KubernetesSecret というエラーで失敗します。
GenesisSecretOutputKubernetesSecret
| フィールド | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
namespace | string | ◯ | - | 出力する Secret の namespace。 |
name | string | ◯ | - | 出力する Secret の name。 |
labels | map<string, string> | - | null | 出力する Secret に付ける labels。 |
annotations | map<string, string> | - | null | 出力する Secret に付ける annotations。 |
type | string | - | Opaque | corev1 の SecretType。空文字列のときは Opaque(厳密には kubernetes.io/opaque ではなく Kubernetes のデフォルト Opaque)として扱われます。kubernetes.io/tls などを指定できます。 |
context | string | - | "" | 構造体上は存在しますが、現バージョンの Manager 実装では参照されません。 出力先クラスタは Tazuna 全体の current-context が使われます。 |
解決の流れ
tazuna apply 時、type: genesissecret の Manifest は次のように処理されます。
manifests[].pathの指す YAML ファイル(tazuna.yaml自身のディレクトリ起点)を読む。spec.secrets[]の各要素を Provider に渡し、フィールド集合を取得する。itemsのmapToでキー名をリネームしながら、すべてのsecrets[]の結果を 1 つのmap[string]stringにマージする(同じキーが衝突した場合は 後勝ち)。spec.outputs[]の各kubernetesSecretについて、namespace/nameを持つ KubernetesSecretをCreateOrUpdateする。StringDataにマージ済みの map がそのまま入る。labels/annotations/typeは宣言どおりに付与される。
tazuna destroy 時も同じ Provider 取得が走り、outputs[].kubernetesSecret の
namespace / name で示される Secret を削除します。
tazuna build 時は、出力対象が outputs[0].kubernetesSecret 1 件分の Secret YAML として
標準出力に書き出されます(複数 outputs を書いていても、build では先頭 1 件のみが対象)。
State と always-sync
GenesisSecret から生成される Secret は、tazuna state diff 上で常に
always-sync 分類になります。
ContentHash で差分判定できる対象ではなく、Provider 側を真実の源として
毎回同期する扱いです。詳細は Diff type /
always-sync を参照してください。
例
最小例:
apiVersion: tazuna.pepabo.com/v1
kind: GenesisSecret
spec:
secrets:
- uri: op://example.1password.com/Platform/aws-credentials
preferLabel: true
items:
accessKeyID:
mapTo: AWS_ACCESS_KEY_ID
secretAccessKey:
mapTo: AWS_SECRET_ACCESS_KEY
outputs:
- kubernetesSecret:
namespace: default
name: aws-credentials
type: kubernetes.io/tls を出力する例:
apiVersion: tazuna.pepabo.com/v1
kind: GenesisSecret
spec:
secrets:
- uri: op://example.1password.com/Platform/tls-wildcard
preferLabel: true
items:
certificate:
mapTo: tls.crt
privateKey:
mapTo: tls.key
outputs:
- kubernetesSecret:
namespace: ingress-nginx
name: wildcard-tls
type: kubernetes.io/tls
labels:
managed-by: tazuna
関連
tazuna.yaml側からの参照:tazuna.yamlManifest type 別フィールド- Provider の語彙: Provider (SecretProvider)
- 既存 Secret を 1Password と GenesisSecret に書き出す:
tazuna secret-to-genesissecret - 用語: GenesisSecret