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. 関連記事
- tfstateを手動編集する危険性 — state操作のリスクと代替手段
- moved ブロック — stateを安全に移動する — mv コマンドのコード化
- importブロック vs importコマンド比較 — 既存リソースの取り込み
- state管理とは — tfstateファイルの役割・基本操作
- import ブロック — 既存リソースをTerraform管理下に
- removed ブロック — stateから安全にリソースを外す
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