- 公開日
- 最終更新日
【Terraform】removedブロックでリソースを管理外にする方法
この記事を共有する
目次
はじめに
こんにちは!パーソル&サーバーワークスの三宅です。
本記事では、Terraform 1.7.0で追加された新機能「removedブロック」について解説します。 Terraform管理下のリソースを管理外へ移行する際に役立つ機能ですので、今回は実際に試した内容をご紹介します。
removedブロックとは
Terraform 1.7.0以降で導入された、リソースを実際に削除することなくTerraformの管理から外すための機能です。
Terraformで管理しているリソースはコードから削除すると、terraform apply 実行時に実際のリソースも削除されてしまいます。 しかし、リソースは残したままTerraformの管理だけを外したいユースケースにおいて、removedブロックが有効な選択肢となります。
removedブロックを使用することで、実リソースを保持したままstateファイルからのみ削除できるようになりました。
公式ドキュメント: removed block reference | Terraform | HashiCorp Developer
removedブロックがない場合を考えてみる
リソースをTerraform管理から外す際には、terraform state rmコマンドを使う方法が一般的です。
$ terraform state rm aws_instance.example
しかし、この方法には以下のような問題がありました。
- 手動でのstate操作が必要でヒューマンエラーのリスクがある
- チーム開発時に誰がどのリソースをいつ管理外にしたか追跡しづらい
- CI/CDパイプラインに組み込みにくい
removedブロックを使った解消方法
removedブロックを使用すると、宣言的にリソースを管理外にできます。
基本的な使い方
まず、以下のようなS3バケットが terraform apply で作成され、管理されている状態を想定します。
# S3バケットを作成する
resource "aws_s3_bucket" "test_bucket" {
bucket = "20251028-test-s3-bucket"
}
このリソースを管理外にする場合、以下のように変更します。
# S3リソースブロックを削除、またはコメントアウトする
# resource "aws_s3_bucket" "test_bucket" {
# bucket = "20251028-test-s3-bucket"
# }
# removedブロックを追記する
removed {
from = aws_s3_bucket.test_bucket
lifecycle {
# falseに設定するとリソースが削除されない (デフォルトはtrueなので必ず指定)
destroy = false
}
}
ポイントは、resourceブロックを削除する代わりにremovedブロックを追加することです。 これによって、Terraformに「このリソースは管理から外すが、削除はしない」という意図を明示的に伝えられます。
この状態で terraform apply を実行すると、以下のような出力が表示されます。
$ terraform apply
Terraform will perform the following actions:
# awss3bucket.test_bucket will no longer be managed by Terraform, but will not be destroyed
# (destroy = false is set in the configuration)
. resource "aws_s3_bucket" "test_bucket" {
...
}
Plan: 0 to add, 0 to change, 0 to destroy.
メッセージを見ると、「Terraformの管理対象外になるが、削除はされない」ことが明確に示されています。 applyを実行すると、stateファイルからリソースの記録が削除されますが、実際のAWSリソース(S3バケット)はそのまま残ります。

上図のように、AWSコンソールで確認すると、S3バケットは削除されずに存在し続けていることがわかります。
複数のリソースを一度に管理外にする
removedブロックは、モジュール内のリソースを管理外にする際にも有効です。 今回は、以下のシンプルなディレクトリ構成で試してみます。
TERRAFORM-REMOVED-TEST/
├── modules/
│ ├── s3/
│ └── vpc/
├── main.tf
├── provider.tf
ルートモジュール(main.tf)には、VPCモジュールとS3モジュールの2つが定義されているとします。
module "my_vpc" {
source = "./modules/vpc"
vpc_name = "example-vpc"
vpc_cidr = "10.0.0.0/16"
public_subnet_cidr = "10.0.1.0/24"
availability_zone = "us-west-2a"
}
module "my_s3" {
source = "./modules/s3"
bucket_name = "20251029-test-bucket"
versioning_enabled = true
}
初期構築後、S3モジュールのみをTerraform管理から外したい場合は、以下のように記述します。
module "my_vpc" {
source = "./modules/vpc"
vpc_name = "example-vpc"
vpc_cidr = "10.0.0.0/16"
public_subnet_cidr = "10.0.1.0/24"
availability_zone = "us-west-2a"
}
# S3モジュールの定義は削除
# removedブロックを追記する
removed {
from = module.my_s3
lifecycle {
destroy = false
}
}
terraform apply を実行すると、以下のような出力になります。
$ terraform apply
Terraform will perform the following actions:
# module.mys3.awss3bucket.this will no longer be managed by Terraform, but will not be destroyed
# (destroy = false is set in the configuration)
. resource "awss3_bucket" "this" {
...
}
Plan: 0 to add, 0 to change, 0 to destroy.
実際に削除もしたい場合
destroy = true を指定すると、リソースを削除できます。
removed {
from = aws_instance.example
lifecycle {
destroy = true
}
}
注意点
removedブロックを使用する際の注意点をいくつか紹介します。
Terraform 1.7.0以降が必要
removedブロックはTerraform 1.7.0で導入された機能のため、それ以前のバージョンでは使用できません。 今回のTerraformバージョンは以下になります。
$ terraform version
Terraform v1.13.4
on linux_amd64
デフォルトの挙動に注意
removedブロックでlifecycleを指定しない場合、デフォルトでdestroy = trueとなり、実際にリソースが削除されてしまいます。
removed {
from = aws_s3_bucket.test_bucket
# lifecycleを指定しない場合、destroy = true(削除される)
}
リソースを残したまま管理から外したい場合は、必ずdestroy = falseを明示的に指定してください。
まとめ
removedブロックを使用することで、リソースを実際に削除せずにTerraformの管理から外すことが宣言的に行えるようになりました。 terraform state rm を使った方法と比較して、以下のようなメリットがあります。
- コードで管理できるため変更履歴が追跡可能
- チーム開発での共有が容易
- CI/CDパイプラインへの組み込みがしやすい
- ヒューマンエラーのリスクが減少
Terraform 1.7.0以降を使用している場合は、リソースを管理外にする際にremovedブロックの使用を検討してみてください。 この記事がどなたかの参考になれば幸いです。
この記事は私が書きました
三宅 啓右
記事一覧2025 Japan All AWS Certifications Engineers 猫派でしたが最近犬派になりました。