Terraform State

Terraform がインフラの現在の状態を管理するファイルとリモートバックエンド

IaC

Terraform State とは

Terraform State は、Terraform が管理するインフラリソースの現在の状態を記録する JSON ファイル (terraform.tfstate) である。Terraform は設定ファイル (.tf) と State を比較して、何を作成・変更・削除するかを決定する。

見落としやすいのは、State が「前回の実行結果の記録」であって実インフラそのものではない点だ。terraform plan は既定で、まず既存リソースの現状を読み直して State を最新化し、そのうえで設定と比較して変更案を組み立てる (2026 年 8 月時点の Terraform CLI ドキュメント)。だから State が実態からずれていても、そのずれは plan の差分として現れる。

terraform plan の 3 段:
  1. 実リソースの現状を読み直して State を最新化
  2. 設定ファイル (.tf) と State を比較
  3. 差分を実行すべき変更として提示

State がないとどうなるか

State がなければ、Terraform は既存のリソースを認識できない。terraform apply を実行するたびに、既存のリソースを無視して新しいリソースを作成しようとする。State は「Terraform が管理しているリソースの一覧」だ。

リモートバックエンド

State ファイルをローカルに保存すると、チームメンバー間で共有できず、同時に terraform apply を実行すると State が壊れる。リモートバックエンドで State を一元管理する。

S3 バックエンド (AWS での定番)

terraform {
  backend "s3" {
    bucket       = "myapp-terraform-state"
    key          = "prod/terraform.tfstate"
    region       = "ap-northeast-1"
    use_lockfile = true  # S3 上のロックファイルで排他を取る
    encrypt      = true
  }
}
  • S3: State ファイルの保存 (バージョニング有効)
  • use_lockfile: ステートロック。State と同じバケットに <key>.tflock というオブジェクトを作って排他を取る (既定値は無効)
  • 暗号化: State には秘密値が入り得るため有効にしておく

ロックの取り方は歴史的に変わっている。以前は dynamodb_table に専用テーブルを指定する構成が定番だった。S3 ネイティブのロックは Terraform 1.10 (2024 年 11 月) で追加され、1.11 (2025 年 2 月) で正式機能になると同時に DynamoDB 系の引数が非推奨になった。公式ドキュメントは 2026 年 8 月時点で、DynamoDB によるロックは非推奨で将来のマイナーバージョンで削除されると明記している。古い構成から移る間は S3 と DynamoDB の引数を同時に指定して両方からロックを取れる。

State に含まれる機密情報

State ファイルにはリソースの属性値がそのまま記録される。公式ドキュメントが例に挙げるのは DB の初期パスワードや API トークンで、設定に書いた秘密値はローカル保存なら平文のファイルに残る。plan ファイルも同じ性質を持つ。逆に IAM ロールの ARN のような識別子は秘匿情報ではない。State を危険にするのは識別子の有無ではなく、値そのものが記録される種類の属性が含まれるかどうかだ。

対策:

  • S3 バケットの暗号化 (SSE-S3 or SSE-KMS)
  • S3 バケットのパブリックアクセスブロック
  • State ファイルを Git にコミットしない (.gitignore に追加)

ステートロック

2 人が同時に terraform apply を実行すると、書き込みが競合して State が壊れる。ロックを有効にしていれば、先に取得した側だけが実行に進み、後から来た側はロック取得に失敗して中断する。ロックは opt-in の機能で、use_lockfile を有効にしない限り働かない点に注意する。

User A: terraform apply → ロック取得 (<key>.tflock を作成) → 実行中...
User B: terraform apply → ロック取得に失敗して中断
User A: 完了 → ロック解放 (<key>.tflock を削除)
User B: terraform apply → ロック取得 → 実行

SAM/CloudFormation との違い

SAM/CloudFormation は状態を AWS 側 (CloudFormation スタック) で管理するため、State ファイルの保管も排他制御も利用者が用意しなくてよい。Terraform はそこを自前で組む必要がある代わりに、AWS 以外のプロバイダーも同じ書き方で扱える。分かれ目は「対象が AWS だけで完結するか」だ。

State の管理方法

選ぶときの軸は 3 つある。State をどこに置くか、同時実行をどこで止めるか、実行環境まで外部に預けるか。人数が増えた時点でローカル保存は成立しなくなる。

方法説明推奨
ローカルファイルシステムに保存1 人での試行までに留める。複数人だと上書きで履歴を失う
S3 バックエンドリモートバックエンドState を S3 に置き、use_lockfile で排他を取る。Terraform 1.10 (2024 年 11 月) より前は DynamoDB のテーブルで排他を取る構成が定番で、1.11 (2025 年 2 月) 以降その引数は非推奨
HCP Terraformマネージドサービス保存と排他制御を任せられる。実行環境まで預けたい場合に選ぶ。2024 年 4 月に Terraform Cloud から改称した

Terraform State の関連書籍も参考になる。

この記事は役に立ちましたか?

関連用語

関連する記事