🍋

Terraform v1.11.0のWrite-Only Attributesについて

2025/02/28に公開

2025年2月21日にv1.11.0-rc3がリリースされたので1週間以内にv1.11.0リリースがあると思って毎日チェックしてました。

新機能

  1. 書き込み専用属性の追加
    プロバイダー側でリソースの属性を「書き込み専用」として指定できるようになりました。
  2. terraform testのJUnit XML出力オプションの一般提供
    terraform testコマンドに-junit-xmlオプションが利用可能になりました。
  3. S3ネイティブ状態ロックの一般提供
    S3を利用した状態ロック機能がuse_lockfile引数を使うことで有効化できるようになり、DynamoDB関連の引数は非推奨となりました。

今回は書き込み専用属性の追加について触れたいと思います。

簡単に言うと、
Terraformがリソース作成時に機密情報を一時的に渡すための仕組みです。

用途

RDSの初回作成時に一時的なパスワードを渡し、Terraformの状態に機密情報が残らないようにし、その後は外部のシークレット管理システム(AWSSecretsManager)で運用するケースがまずは思い浮かびます。

実装

利用できるプロバイダーのバージョンは5.89です

terraform {
  required_version = "~> 1.11.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.89"
    }
  }
}

password_woでephemeralを参照し、password_wo_versionでバージョンを定義します。
作成されたパスワードはもちろんoutputでもdataでも参照できません。

ephemeral "random_password" "password_wo" {
  length = 16
}

resource "aws_db_instance" "password_wo" {
// 省略
password_wo            = ephemeral.random_password.password_wo.result
password_wo_version    = 1

lifecycle {
  ignore_changes = [password_wo]
}

tfstateには文字列リテラルでなく、nullとして記述されるようになっています。password_wo_versionの値は定義されますので、ephemeralでパスワードを運用していく場合はpassword_wo_versionをインクリメントしていく必要があります。

"password": null,
"password_wo": null,
"password_wo_version": 1,

想定する運用方法

flowchart TD
    A[Terraform: password_woとpassword_wo_versionで初期パスワード作成]
    B[Terraform: lifecycleでignore_changesを設定]
    C[初期パスワード適用 (tfstateにはパスワードが保存されない)]
    D[SecretsManagerに新パスワード登録]
    E[IAM認証でサーバにログインしてパスワード変更]
    F[最終的にtfstateに機密情報が残らず、差分も発生しない]

    A --> B
    B --> C
    C --> D
    D --> E
    E --> F

Discussion