terraform state コマンド完全ガイド — mv / rm / list / show

1. 概要

  • terraform state list — stateのリソース一覧
  • terraform state show — リソースの詳細表示
  • terraform state mv — stateのリソース移動・リネーム
  • terraform state rm — stateからリソースを削除
  • terraform state pull / push — stateの手動取得・アップロード

terraform stateコマンド群は、tfstateファイルを直接操作するための高度なコマンドです。リソースのリネーム、moduleへの移行、手動作成リソースのstateへの追加、破損したstateの修復に使います。

重要: terraform stateコマンドはstateを直接変更します。実行前にバックアップを取り、チームに共有してから実行してください。


2. terraform state list — リソース一覧

# すべてのリソースを一覧表示
$ terraform state list
aws_instance.web
aws_s3_bucket.app_data
aws_vpc.main
aws_subnet.private[0]
aws_subnet.private[1]
module.network.aws_vpc.main
module.network.aws_subnet.private[0]

# フィルタリング(部分一致)
$ terraform state list aws_instance.*
aws_instance.web

# moduleのリソースのみ
$ terraform state list module.network.*
module.network.aws_vpc.main
module.network.aws_subnet.private[0]

3. terraform state show — リソースの詳細表示

# リソースの現在の属性値を表示
$ terraform state show aws_instance.web
# aws_instance.web:
resource "aws_instance" "web" {
    ami                    = "ami-0123456789abcdef0"
    arn                    = "arn:aws:ec2:ap-northeast-1:123456789012:instance/i-1234567890abcdef0"
    id                     = "i-1234567890abcdef0"
    instance_type          = "t3.micro"
    private_ip             = "10.0.1.45"
    public_ip              = null
    tags                   = {
        "Environment" = "dev"
        "ManagedBy"   = "terraform"
        "Name"        = "dev-web"
    }
    # ... 他の属性
}

4. terraform state mv — リソースの移動・リネーム

リソースを削除して再作成せずに、stateのみを変更します。

# リソースをリネーム
$ terraform state mv aws_instance.web aws_instance.web_server

# リソースをmoduleに移動
$ terraform state mv aws_vpc.main module.network.aws_vpc.main

# for_eachに変更した場合のキーの付与
$ terraform state mv 'aws_subnet.private[0]' 'aws_subnet.private["ap-northeast-1a"]'

よくあるユースケース:

# 変更前: ルートモジュールに直書き
resource "aws_vpc" "main" { ... }

# 変更後: moduleに移動
module "network" {
  source = "./modules/network"
}
# → modules/network/main.tf に aws_vpc.main がある
# mvコマンドでstateを更新(VPCが削除・再作成されない)
$ terraform state mv aws_vpc.main module.network.aws_vpc.main

5. terraform state rm — stateからリソースを削除

Terraformの管理対象から外すが、AWSリソースは残す場合に使います。

# stateから削除(AWSリソースは残る)
$ terraform state rm aws_instance.legacy

# moduleごとstateから削除
$ terraform state rm module.old_module

注意: state rm後、そのリソースはTerraformが管理しなくなります。コードからも削除しないと次のplanで「新規作成」と判定されます。


6. terraform state pull / push

# リモートstateをローカルに取得(バックアップ作成に使う)
$ terraform state pull > backup_$(date +%Y%m%d_%H%M%S).tfstate

# 修正したstateをリモートにアップロード(危険)
$ terraform state push modified.tfstate

7. 実践例: countからfor_eachへの移行

# 変更前
resource "aws_subnet" "private" {
  count      = 2
  vpc_id     = aws_vpc.main.id
  cidr_block = cidrsubnet("10.0.0.0/16", 8, count.index)
}

# 変更後
resource "aws_subnet" "private" {
  for_each          = toset(["ap-northeast-1a", "ap-northeast-1c"])
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet("10.0.0.0/16", 8, index(tolist(toset(["ap-northeast-1a", "ap-northeast-1c"])), each.key))
  availability_zone = each.key
}
# countのインデックスからfor_eachのキーへ移行
$ terraform state mv 'aws_subnet.private[0]' 'aws_subnet.private["ap-northeast-1a"]'
$ terraform state mv 'aws_subnet.private[1]' 'aws_subnet.private["ap-northeast-1c"]'

8. 関連記事


9. まとめ

  • state list — stateのリソース一覧。module・リソースタイプでフィルタ可能
  • state show — リソースの現在の属性値を詳細表示
  • state mv — リソースのリネーム・module移動(削除・再作成なし)
  • state rm — stateから除外(AWSリソースは残る)
  • state pull/push — stateのバックアップ・緊急時の修復
  • 実行前は必ずstate pullでバックアップを取ること

動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/cli/commands/state