基本機能

状態管理

Terraformの状態管理は、インフラストラクチャの現在の状態を追跡し、コードと実際のリソースの差分を検出するための重要な機能です。このページでは、状態ファイルの役割、管理方法、ベストプラクティスについて説明します。
最終更新: 2026/2/3

状態管理

Terraformの状態管理は、インフラストラクチャの現在の状態を追跡し、コードと実際のリソースの差分を検出するための重要な機能です。このページでは、状態ファイルの役割、管理方法、ベストプラクティスについて説明します。

状態ファイルとは

状態ファイル(terraform.tfstate)は、Terraformが管理しているインフラストラクチャの現在の状態を記録するJSONファイルです。

状態ファイルの役割

  1. リソースのマッピング: Terraformの設定と実際のリソースを紐付け
  2. メタデータの保存: リソース間の依存関係や属性値を記録
  3. パフォーマンスの最適化: APIコールを削減し、大規模なインフラでも高速に動作
  4. チームでの協調作業: 状態を共有することで、複数人での作業を可能に

状態ファイルの内容

{
  "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は慎重に使用してください。誤った状態をプッシュすると、インフラストラクチャの管理に問題が発生する可能性があります。

状態のロック

リモートバックエンドを使用すると、状態のロック機能が利用できます。

ロックの仕組み

  1. terraform applyを実行すると、状態ファイルがロックされます
  2. 他のユーザーは同時に変更できません
  3. 操作が完了すると、ロックが解除されます

ロックの強制解除

操作が中断された場合、ロックが残ることがあります。

# ロック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

次のステップ

状態管理の基本を理解したら、次はモジュールについて学びましょう。

参考リンク

© 2026 IBM Corporation. Licensed under CC BY 4.0.