Terraform では、コードからリソース定義を削除すると通常は destroy が計画されます。運用上「作った実物は残したいが、Terraform の管理からは外したい」場面では、それでは困ります。
removed ブロックは、このギャップを埋めるための宣言的な state 操作です。CLI での terraform state rm のような単発操作をコードに置き換え、レビュー/再現可能な形で“忘れる”ことを実現します。
removed ブロックは、既存の管理対象リソースを破壊せずに Terraform の状態管理から外すための宣言です。適用時にプロバイダへ destroy は依頼されず、対応する state エントリが削除されます。実インフラ上のリソースはそのまま残ります。
想定ユースケースは、ログ保管用バケット等を別ツールや手動運用に引き渡す、検証中のみ Terraform 管理していた一時的リソースを管理外に戻す、チーム内のレビュー可能な形で state からの削除を行いたい、などです。
removed はトップレベルブロックで記述し、from に“これまで管理していたオブジェクトのアドレス”を指定します。count/for_each のインスタンスにもインデックス/キー指定で対応できます。プラン時に Terraform は、該当の state エントリを destroy ではなく “state からの削除”として解釈します。
適用順序としては、通常の差分解決の一環で removed の処理が行われます。対象が state に存在しなければ何も起きません。適用後は、removed ブロック自体をコードから削除して構いません(移行のための一時的な宣言です)。
removed による計画と適用の流れ
removed は “管理外にする” ための手段です。名前変更やアドレスの変更は moved、即時に手元だけで state をいじるなら terraform state rm、実インフラを削除したいなら destroy を使います。試験でもこの区別が頻出です。
特に、コードからリソース定義を消すだけでは destroy が計画される点に注意が必要です。destroy を抑止して state から忘れたいときに removed を併用します。
| 手段 | 主目的 | 実インフラへの影響 | 宣言/レビュー適性 |
|---|---|---|---|
| removed ブロック | 管理対象から外す(state から忘れる) | 削除しない(実物は残る) | 高い(コードに残せる) |
| moved ブロック | リソース/モジュールのアドレス変更 | 削除しない(実物は維持) | 高い(コードで追跡可能) |
| terraform state rm | 手動で state から削除 | 削除しない(実物は残る) | 低い(都度コマンド、再現性・レビューが弱い) |
| terraform destroy / -target | 実物の削除 | 削除する(プロバイダに destroy) | 中(計画は見えるが宣言としては残らない) |
例として、監査ログ用の aws_s3_bucket.logs を今後はセキュリティチームが直接管理することになり、Terraform の対象からは外したいが、実物は消さない要件を考えます。コードから単に削除すると destroy が計画されるため、removed を使います。
適用後は state から該当バケットが消え、以降の plan で Terraform はこのバケットを参照しなくなります。他リソースが参照している場合は、参照の差し替え(データソース、外部入力、変数化など)を先に済ませてから実行してください。
HCL 例: S3 バケットを管理外にする
# Terraform >= 1.6 を想定
# 既存: aws_s3_bucket.logs が state に存在
terraform {
required_version = ">= 1.6.0"
}
# 以前はここに aws_s3_bucket.logs の定義があったが削除済み
# 破壊せずに state から外したい
removed {
from = "aws_s3_bucket.logs"
}
# count/for_each の特定インスタンスを外す例
# removed {
# from = "aws_iam_user.legacy[\"temp\"]"
# }
依存関係の解決順序に注意します。removed の対象を他リソースが参照していると、参照切れで plan が失敗します。先に参照元を置き換える(データソース化、外部入力に切替、ハードコード回避)か、分割して適用します。
状態の整合性を保つため、PR に removed を含めてレビューを通し、適用後に no-op を確認してから removed ブロックを削除する運用が安全です。CLI の state rm を混在させる場合は、誰がいつ実施したかの監査ログと手順書を残します。
removed と moved の違い、destroy の挙動の違いを正確に説明できることが求められます。シナリオ問題では「実物は残す」「管理から外す」「アドレスを変える」をキーワードとして読み取り、最適なブロックまたはコマンドを選択します。
また、count/for_each の個別インスタンス指定、適用後に removed をコードから削除できる一時的宣言である点、チーム運用では宣言的アプローチ(removed/moved)を優先する、などが問われやすいです。
Pro
問題 1
あるチームは、既存の監査ログ用 S3 バケットを今後はセキュリティ部門が手動で管理する方針に変更した。バケットは削除してはならない。Terraform のコードから当該バケット定義は削除済みで、現在の plan では destroy が提案されている。最も適切な対応はどれか。
正解: A
要件は「削除せずに Terraform 管理から外す」こと。removed は destroy を行わず state から忘れるため適合する。moved はアドレス変更用、destroy は削除してしまう、ignore_changes は設定差分を無視するだけで state から外さない。
removed は data リソースにも使えますか?
一般に対象は管理対象リソースのインスタンスです。data ソースは実インフラを作らず、state にも管理対象としては保持しないため、removed の出番は通常ありません。
removed を永続的にコードへ残しても良いですか?
適用が完了し no-op を確認したら削除するのが推奨です。removed は移行のための一時的宣言であり、残し続ける必要はありません。
同じアドレスに対して moved と removed を同時に書くとどうなりますか?
意味が競合します。アドレス変更(moved)か、管理外化(removed)のどちらか一方を選びます。段階的な移行が必要なら、まず moved でアドレス整合をとり、その後に別のリソースを removed で管理外にするなど、計画を分割してください。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける
Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...
Terraform Authoring & Ops Pro: 上位資格の範囲と対策
上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...
Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす
Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...
Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義
Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...
Terraform Data Source徹底理解:既存リソースの参照で壊さず足す
Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...