基本機能
状態管理
Terraformの状態管理は、インフラストラクチャの現在の状態を追跡し、コードと実際のリソースの差分を検出するための重要な機能です。このページでは、状態ファイルの役割、管理方法、ベストプラクティスについて説明します。
最終更新: 2026/2/3
状態管理
Terraformの状態管理は、インフラストラクチャの現在の状態を追跡し、コードと実際のリソースの差分を検出するための重要な機能です。このページでは、状態ファイルの役割、管理方法、ベストプラクティスについて説明します。
状態ファイルとは
状態ファイル(terraform.tfstate)は、Terraformが管理しているインフラストラクチャの現在の状態を記録するJSONファイルです。
状態ファイルの役割
- リソースのマッピング: Terraformの設定と実際のリソースを紐付け
- メタデータの保存: リソース間の依存関係や属性値を記録
- パフォーマンスの最適化: APIコールを削減し、大規模なインフラでも高速に動作
- チームでの協調作業: 状態を共有することで、複数人での作業を可能に
状態ファイルの内容
{
"version": 4,
"terraform_version": "1.7.0",
"serial": 1,
"lineage": "...",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_instance",
"name": "web",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"id": "i-1234567890abcdef0",
"ami": "ami-0c55b159cbfafe1f0",
"instance_type": "t2.micro",
...
}
}
]
}
]
}
状態ファイルには機密情報(パスワード、APIキーなど)が含まれる可能性があります。適切に保護してください。
ローカル状態管理
デフォルトでは、状態ファイルはローカルに保存されます。
ローカル状態の利点
- シンプル: 追加の設定が不要
- 高速: ネットワーク遅延がない
- 学習に最適: 個人プロジェクトや学習目的に適している
ローカル状態の制限
- チーム作業が困難: 状態ファイルを共有できない
- 同時編集の問題: 複数人が同時に変更すると競合が発生
- バックアップが必要: 手動でバックアップを管理する必要がある
# ローカル状態ファイルの場所
./terraform.tfstate
./terraform.tfstate.backup # 前回の状態のバックアップ
リモート状態管理
本番環境やチーム開発では、リモートバックエンドの使用が推奨されます。
リモート状態の利点
- チームでの協調作業: 状態を共有できる
- 状態のロック: 同時編集を防止
- 自動バックアップ: クラウドプロバイダーが自動的にバックアップ
- セキュリティ: 暗号化とアクセス制御
S3バックエンド(AWS)
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
dynamodb_table = "terraform-lock"
}
}
設定項目:
bucket: 状態ファイルを保存するS3バケットkey: 状態ファイルのパスregion: S3バケットのリージョンencrypt: サーバーサイド暗号化を有効化dynamodb_table: 状態ロック用のDynamoDBテーブル
DynamoDBテーブルの作成:
resource "aws_dynamodb_table" "terraform_lock" {
name = "terraform-lock"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
Azure Blob Storage バックエンド
terraform {
backend "azurerm" {
resource_group_name = "terraform-state-rg"
storage_account_name = "tfstatestorage"
container_name = "tfstate"
key = "prod.terraform.tfstate"
}
}
Google Cloud Storage バックエンド
terraform {
backend "gcs" {
bucket = "my-terraform-state"
prefix = "prod"
}
}
Terraform Cloud バックエンド
terraform {
cloud {
organization = "my-organization"
workspaces {
name = "my-workspace"
}
}
}
バックエンドの初期化と移行
初回設定
バックエンドを設定したら、初期化が必要です。
terraform init
ローカルからリモートへの移行
# 1. backend設定を追加
# 2. 再初期化
terraform init -migrate-state
# 確認プロンプトが表示されます
Do you want to copy existing state to the new backend?
Enter a value: yes
リモートからローカルへの移行
# 1. backend設定を削除
# 2. 再初期化
terraform init -migrate-state
状態ファイルの操作
Terraformは、状態ファイルを直接編集するのではなく、専用のコマンドを使用して操作します。
terraform state list
管理されているリソースの一覧を表示します。
terraform state list
出力例:
aws_instance.web
aws_s3_bucket.logs
aws_vpc.main
terraform state show
特定のリソースの詳細を表示します。
terraform state show aws_instance.web
出力例:
# aws_instance.web:
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
id = "i-1234567890abcdef0"
...
}
terraform state mv
リソースの名前を変更します。
# リソース名の変更
terraform state mv aws_instance.web aws_instance.web_server
# モジュール間の移動
terraform state mv aws_instance.web module.web.aws_instance.server
terraform state rm
状態ファイルからリソースを削除します(実際のリソースは削除されません)。
terraform state rm aws_instance.web
terraform state rmは状態ファイルからのみ削除します。実際のリソースを削除するには、terraform destroyを使用してください。terraform state pull
リモート状態をローカルに取得します。
terraform state pull > terraform.tfstate.backup
terraform state push
ローカル状態をリモートにプッシュします。
terraform state push terraform.tfstate
terraform state pushは慎重に使用してください。誤った状態をプッシュすると、インフラストラクチャの管理に問題が発生する可能性があります。状態のロック
リモートバックエンドを使用すると、状態のロック機能が利用できます。
ロックの仕組み
terraform applyを実行すると、状態ファイルがロックされます- 他のユーザーは同時に変更できません
- 操作が完了すると、ロックが解除されます
ロックの強制解除
操作が中断された場合、ロックが残ることがあります。
# ロックIDを確認
terraform force-unlock <LOCK_ID>
ロックの強制解除は、他のユーザーが操作していないことを確認してから行ってください。
ワークスペース
ワークスペースを使用すると、同じ設定で複数の環境を管理できます。
ワークスペースの作成と切り替え
# ワークスペースの一覧
terraform workspace list
# 新しいワークスペースの作成
terraform workspace new production
terraform workspace new staging
terraform workspace new development
# ワークスペースの切り替え
terraform workspace select production
# 現在のワークスペースを確認
terraform workspace show
ワークスペースの活用
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = terraform.workspace == "production" ? "t2.large" : "t2.micro"
tags = {
Name = "web-${terraform.workspace}"
Environment = terraform.workspace
}
}
各ワークスペースは独立した状態ファイルを持ちます:
terraform.tfstate.d/
├── production/
│ └── terraform.tfstate
├── staging/
│ └── terraform.tfstate
└── development/
└── terraform.tfstate
ベストプラクティス
1. リモートバックエンドを使用
# 推奨: リモートバックエンド
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
}
}
2. 状態ファイルをバージョン管理に含めない
# .gitignore
*.tfstate
*.tfstate.*
.terraform/
3. 状態のロックを有効化
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
dynamodb_table = "terraform-lock" # ロックを有効化
}
}
4. 環境ごとに状態を分離
# 本番環境
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/terraform.tfstate"
region = "ap-northeast-1"
}
}
# ステージング環境
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "staging/terraform.tfstate"
region = "ap-northeast-1"
}
}
5. 定期的なバックアップ
# 状態ファイルのバックアップ
terraform state pull > backup-$(date +%Y%m%d-%H%M%S).tfstate
6. 状態ファイルへのアクセス制御
- IAMポリシーで適切なアクセス権限を設定
- 暗号化を有効化
- 監査ログを有効化
トラブルシューティング
状態ファイルの破損
# バックアップから復元
cp terraform.tfstate.backup terraform.tfstate
# または、リモート状態から取得
terraform state pull > terraform.tfstate
状態の不整合
# 実際のインフラと状態を同期
terraform refresh
# または、再度planとapplyを実行
terraform plan
terraform apply
状態ファイルの競合
# ロックを確認
terraform force-unlock <LOCK_ID>
# 最新の状態を取得
terraform state pull
次のステップ
状態管理の基本を理解したら、次はモジュールについて学びましょう。