ota2000
2 min read

Cloudflare Pages の環境変数を Terraform で管理する際のハマりどころ

Cloudflare Pages のビルド環境変数を Terraform で管理しようとしてハマった話。

provider v5 での書き方

Cloudflare Terraform provider v5 では、Pages プロジェクトの環境変数は deployment_configs.env_vars で設定する。v4 以前の environment_variables とは変わっている。

resource "cloudflare_pages_project" "site" {
  # ...
  deployment_configs = {
    production = {
      env_vars = {
        MY_VAR = {
          type  = "plain_text"
          value = var.my_var
        }
      }
    }
  }
}

type には plain_textsecret_text を指定できる。

secret_text が壊れている

secret_text を指定すると、Cloudflare API は読み取り時に値を返さない。セキュリティとしては正しい。ただ、Terraform にとっては致命的だった。

  1. terraform applysecret_text の値を設定する
  2. 次の terraform plan で API から state を refresh する
  3. API が値を返さないので、Terraform は state に空文字列を書き込む
  4. 次の apply でその空文字列が Cloudflare に送信される

要するに、secret_text で設定した値は次の apply で消える。terraform state show では (sensitive value) と表示されていて一見正しく見えるが、中身は空文字列だった。

ダッシュボードで確認したら変数名だけあって値が空。ビルドは RESUME_PASSWORD が未設定でエラー。原因の特定に少し時間がかかった。

対処法

plain_text を使って、Terraform 変数側で sensitive = true にする。

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

Terraform Cloud で Sensitive 変数として登録すれば、plan/apply のログには値が出ない。Cloudflare のダッシュボード上では「プレーンテキスト」と表示されるが、ビルド環境変数なので実用上は問題ない。

provider のバグとして報告されるべき挙動だが、現時点では plain_text + sensitive variable が確実な回避策になる。