Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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: genesissecretpathYAML ファイル 1 つを直接指します (他の Manifest type のようにディレクトリを指すのではありません)。

ルート (GenesisSecret)

フィールド必須デフォルト説明
apiVersionstring--スキーマバージョンを示します。値は現状検証されません。
kindstring--リソース種別を示します。値は現状検証されません。
specGenesisSecretSpec-GenesisSecret 本体。

apiVersion / kind のフィールドは構造体に対応する宣言がなく、書いても 読まれずに無視されますが、慣習として apiVersion: tazuna.pepabo.com/v1 / kind: GenesisSecret を書いておくと、後から検証が入っても揃えやすくなります。

GenesisSecretSpec

フィールド必須デフォルト説明
providerstring-""取得元 Provider の指定。現バージョンの Manager は値を参照していません。 Provider は Tazuna 全体で 1 つ(1Password 向け実装)が組み込まれていて、tazuna apply の起動時に決定されます。
secrets[GenesisSecretGenerate]-取得対象。複数書けます。
outputs[GenesisSecretOutput]-出力先。複数書けます。

GenesisSecretGenerate

secrets[] の各要素です。1 つの「Provider 上のアイテム」を表します。

フィールド必須デフォルト説明
uristring-Provider 上のアイテムを指す URI。詳細は uri の形式 参照。
itemsmap<string, GenesisSecretGenerateItem>-Provider から取得した key と、出力 Secret 上のキー名の対応表。
preferLabelbool-falseProvider が返したフィールドを ラベル名 でキー化するかどうか。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)。

フィールド必須デフォルト説明
mapTostring-出力先 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 つの「出力先」を表します。

フィールド必須デフォルト説明
kubernetesSecretGenesisSecretOutputKubernetesSecret△ (※)null出力先として Kubernetes Secret を作る場合に指定します。
stdoutobject-nullスキーマ上は存在しますが 現バージョンでは未対応 です。kubernetesSecretnull の場合は実行時にエラーになります。

(※) 現バージョンでは outputs[] の各要素は kubernetesSecret を必須 とします。 構造体上は stdout も存在しますが、kubernetesSecret == nil だと .spec.output currently supports only KubernetesSecret というエラーで失敗します。

GenesisSecretOutputKubernetesSecret

フィールド必須デフォルト説明
namespacestring-出力する Secret の namespace。
namestring-出力する Secret の name。
labelsmap<string, string>-null出力する Secret に付ける labels。
annotationsmap<string, string>-null出力する Secret に付ける annotations。
typestring-Opaquecorev1 の SecretType。空文字列のときは Opaque(厳密には kubernetes.io/opaque ではなく Kubernetes のデフォルト Opaque)として扱われます。kubernetes.io/tls などを指定できます。
contextstring-""構造体上は存在しますが、現バージョンの Manager 実装では参照されません。 出力先クラスタは Tazuna 全体の current-context が使われます。

解決の流れ

tazuna apply 時、type: genesissecret の Manifest は次のように処理されます。

  1. manifests[].path の指す YAML ファイルtazuna.yaml 自身のディレクトリ起点)を読む。
  2. spec.secrets[] の各要素を Provider に渡し、フィールド集合を取得する。
  3. itemsmapTo でキー名をリネームしながら、すべての secrets[] の結果を 1 つの map[string]string にマージする(同じキーが衝突した場合は 後勝ち)。
  4. spec.outputs[] の各 kubernetesSecret について、namespace / name を持つ Kubernetes SecretCreateOrUpdate する。
    • StringData にマージ済みの map がそのまま入る。
    • labels / annotations / type は宣言どおりに付与される。

tazuna destroy 時も同じ Provider 取得が走り、outputs[].kubernetesSecretnamespace / 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

関連