terraform.tfstate の役割と S3 + DynamoDB によるリモート管理
🏗️ はじめに
Terraform を使ってインフラを構築するとき、実際のクラウド上の状態を
どのように記録・管理しているのか? を理解することはとても重要です。
Terraform は構築したリソースの情報を「state ファイル」として保存し、
次回の変更や削除時にその状態を参照します。
本章では、terraform.tfstate の役割と構造、
そして S3 + DynamoDB を利用した安全なリモート管理の方法を解説します。
🌍 terraform.tfstate とは?
terraform.tfstate は、Terraform が管理するリソースの「現在の状態」を保持するファイルです。
| 機能 | 説明 |
|---|---|
| 状態の記録 | 作成済みリソースの ID・属性・依存関係を保持 |
| 差分の計算 |
terraform plan 時に、コードとの差分を検出 |
| 一貫性の維持 | 不要な削除や重複作成を防ぐ |
| 機密情報の含有 | パスワードやキーが含まれることがあるため管理注意 |
もしこのファイルを紛失したり壊してしまうと、Terraform は既存リソースを認識できず、
誤って再作成・削除する恐れがあります。
📁 保存場所(ローカルの場合)
デフォルトでは、state ファイルはプロジェクトのルートディレクトリに
terraform.tfstate という名前で保存されます。
terraform init
terraform plan
terraform apply
💡 注意:ローカル state は個人作業には十分ですが、チーム開発では競合や上書きリスクが高いため、
リモート backend(S3 など) の利用が推奨されます。
☁️ リモート state 管理のメリット
| メリット | 説明 |
|---|---|
| 一貫した状態共有 | チーム全員が同じ state を利用可能 |
| 競合防止 | DynamoDB によるロックで同時実行を防ぐ |
| セキュリティ | S3 側の暗号化・アクセス制御により安全性向上 |
| バックアップ | S3 のバージョン管理で過去 state を復元可能 |
⚙️ S3 + DynamoDB による構成例
以下は、S3 に state を保存し、DynamoDB でロックを管理する一般的な設定例です。
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "envs/prod/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
| 項目 | 説明 |
|---|---|
bucket |
S3 バケット名 |
key |
state ファイルの保存パス |
region |
AWS リージョン |
dynamodb_table |
ロック管理に使用する DynamoDB テーブル |
encrypt |
サーバーサイド暗号化を有効化 |
🪣 S3 & DynamoDB の作成例(AWS CLI)
# S3 バケットの作成
aws s3api create-bucket --bucket my-terraform-state-bucket --region ap-northeast-1 --create-bucket-configuration LocationConstraint=ap-northeast-1
# バージョニングを有効化
aws s3api put-bucket-versioning --bucket my-terraform-state-bucket --versioning-configuration Status=Enabled
# DynamoDB テーブルの作成(ロック用)
aws dynamodb create-table --table-name terraform-locks --attribute-definitions AttributeName=LockID,AttributeType=S --key-schema AttributeName=LockID,KeyType=HASH --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5
🔐 IAM 権限の最小ポリシー例
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-terraform-state-bucket",
"arn:aws:s3:::my-terraform-state-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:DeleteItem",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/terraform-locks"
}
]
}
🧭 このポリシーを Terraform 実行ユーザーやロールに付与することで、
S3 への読み書きと DynamoDB ロックの操作が可能になります。
🔄 Terraform のワークフロー
terraform init # backend 初期化
terraform plan # 差分の確認
terraform apply # インフラ構築(自動ロック)
terraform destroy # 削除(ロック解除)
DynamoDB のロック機能により、同時に複数のユーザーが apply を実行しても衝突しません。
🧠 ベストプラクティス
- ✅ S3 バージョニングを有効化してバックアップ確保
- ✅ 暗号化(SSE) と IAM ポリシーでセキュリティ強化
- 🚫 state ファイルを Git にコミットしない
- 🗂️
key名を環境・プロジェクトごとに分ける(例:envs/dev/terraform.tfstate) - ⚠️
terraform state rm / mvは慎重に操作(事前にバックアップ推奨)
🧩 よくあるトラブルと対処
| 症状 | 原因 | 対応策 |
|---|---|---|
| Lock Error | DynamoDB テーブルなし or 権限不足 | テーブル作成・IAM再確認 |
| AccessDenied | IAM 権限設定ミス | S3/DynamoDB ポリシーを確認 |
| 競合発生 | 同時に apply 実行 | ロック解除を確認し再実行 |
| state 壊れた | 手動編集や誤 push | S3 バージョン履歴から復元 |
🧾 まとめ
-
terraform.tfstateは Terraform の「現在の真実」を記録する重要ファイル。 - ローカルよりも S3 + DynamoDB のリモート管理が推奨。
- バージョニング・ロック・暗号化を組み合わせて安全に運用可能。
- チーム開発では「state 管理」が IaC 運用の鍵となる。
🌱 state を制す者が Terraform を制す。