↓メインコンテンツへスキップ
  1. Blogs/

Terraformのwrite-only argumentでSecret Managerへ値を登録してみた

2 分
Terraform GoogleCloud
0222-nnn
著者
0222-nnn
猫が好き
目次
Terraform-GoogleCloud - この記事は連載の一部です
パート 10: この記事

概要
#

TerraformでSecretをそのままgoogle_secret_manager_secret_versionへ書くと、値が平文でPlanやStateに残ります。Stateファイルへのアクセス権限を絞っていても、漏洩の経路が増える課題は残ります。

Terraform 1.11以降のwrite-only argumentを使えば、Secret値をPlanやStateへ残さず登録できます。ここではSecret ManagerへVersionを実際に登録し、値がStateに残らないことを確認します。

Terraformの基本操作は前提としています。Secret Managerを初めて扱う方向けです。

Secretの自動Rotationは扱いません。他ResourceからのSecret参照(例: Cloud Runの環境変数注入)も扱いません。

検証すること
#

  • Secret ManagerのSecretとVersionを作成できること
  • Write-only ArgumentでSecret値をStateへ保存せず登録できること
  • Version番号によってSecret更新をTerraformへ伝えられること
  • Google Cloud CLIで登録結果を確認できること

今回の構成
#

SecretはGlobalなResourceで、Replicationの方式だけを指定します。実体の配置はGoogle Cloudが決めます。

flowchart TB
    subgraph GCP["Google Cloud"]
        subgraph Project["Project"]
            subgraph SM["Secret Manager(Global)"]
                Secret["Secret: tf-example-secret
automatic replication"] Ver["Secret Version 1
enabled"] Secret --- Ver end end end

値の渡し方が要点です。terraform.tfvarsはGit管理外に置き、write-only argumentでStateへ書き込まれないようにします。

sequenceDiagram
    participant Tfvars as terraform.tfvars
(Git管理外) participant TF as Terraform participant State as State participant SM as Secret Manager Tfvars->>TF: sensitive variable で値を渡す TF->>SM: secret_data_wo で送信 Note over TF,State: write-only なので
Stateへは書かない TF->>State: バージョン番号だけ記録 SM-->>TF: Secret Version 1 を作成

secret_data_wo_versionを変えると、Terraformは値が変わったと判断して新しいVersionを作ります。値そのものはStateに残りません。

使用するTerraformコード
#

前提
#

  • Terraform 1.11以上
  • ADCで認証済み
  • Secret Manager Admin相当の権限
  • 検証専用のSecret値
  • 検証時のバージョン:Terraform 1.14.3、google 7.43.0

Secretと自動Replication
#

resource "google_secret_manager_secret" "example" {
  secret_id = var.secret_id

  replication {
    auto {}
  }
}

Secretは値を格納する親Resourceです。実際の値はSecret Versionとして追加します。autoReplicationではGoogle Cloudが保存Locationを管理します。

write-only argument
#

variable "secret_data" {
  type      = string
  sensitive = true
}

variable "secret_data_version" {
  type    = number
  default = 1
}

resource "google_secret_manager_secret_version" "example" {
  secret                 = google_secret_manager_secret.example.id
  secret_data_wo         = var.secret_data
  secret_data_wo_version = var.secret_data_version
}

secret_data_woはwrite-onlyなので、値はProviderへ渡されますがTerraform PlanやStateには保存されません。

値をStateへ保持しないため、Terraformは値そのものの変更を比較できません。Secretを更新するときはsecret_data_wo_versionも増加させ、更新のTriggerとして使います。

sensitive = trueはCLI表示を隠す設定ですが、それだけで通常の値がStateへ保存されなくなるわけではありません。今回のポイントはwrite-only argumentを使用することです。

設定と実行
#

cd Basic-Examples/09-secret-manager
cp terraform.tfvars.example terraform.tfvars
project_id          = "your-project-id"
secret_data         = "replace-with-test-secret"
secret_data_version = 1

terraform.tfvarsはGitへコミットせず、本番のSecretではなく検証専用値を使用します。

terraform init
terraform fmt -check
terraform validate
terraform plan
terraform apply
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Outputs:

secret_id = "tf-example-secret"
secret_name = "projects/YOUR_PROJECT_ID/secrets/tf-example-secret"
secret_version = "1"

GCP側で確認する
#

Metadataを確認します。

gcloud secrets describe \
  "$(terraform output -raw secret_id)" \
  --project=YOUR_PROJECT_ID

値を確認します。Terminal履歴や画面共有への露出に注意してください。

gcloud secrets versions access latest \
  --secret="$(terraform output -raw secret_id)" \
  --project=YOUR_PROJECT_ID

値を変更する場合は次のようにVersion Triggerも更新します。

secret_data         = "new-test-secret"
secret_data_version = 2

後片付けと注意点
#

terraform destroy

Secret Versionの保存やアクセスには料金が発生する場合があります。State Backend自体の暗号化・アクセス制御も引き続き必要です。

まとめ
#

  • SecretとSecret Versionを分けて管理できる
  • write-only argumentでSecret値をStateへ残さず渡せる
  • Version Triggerで値の更新タイミングを管理する
  • tfvars、CLI出力、実行環境からの漏えいにも注意する

参考資料
#

次回
#

次はPub/Sub TopicとPull Subscriptionを作成します。

Terraform-GoogleCloud - この記事は連載の一部です
パート 10: この記事

関連記事

Terraform StateをCloud Storage Remote Backendへ移行してみた
2 分
Terraform GoogleCloud CloudStorage
TerraformからGoogle Cloudへ接続してProject情報を取得してみた
3 分
Terraform GoogleCloud
TerraformでArtifact RegistryのDocker Repositoryを作成してみた
2 分
Terraform GoogleCloud Docker
TerraformでArtifact RegistryのコンテナをCloud Runへデプロイしてみた
2 分
Terraform GoogleCloud CloudRun ArtifactRegistry
TerraformでBigQuery DatasetとTableを作成してみた
2 分
Terraform GoogleCloud
TerraformでCloud KMSのKeyRingとCryptoKeyを作成してみた
2 分
Terraform GoogleCloud