In Terraform, removing a resource definition from code normally schedules a destroy. That is a problem in operations when you want to keep the actual resource you created but stop managing it with Terraform.
The removed block is a declarative state operation that fills this gap. It replaces one-off CLI operations such as terraform state rm with code, letting you “forget” a resource in a reviewable and reproducible way.
The removed block is a declaration that drops an existing managed resource from Terraform state management without destroying it. At apply time, no destroy is requested from the provider; only the corresponding state entry is removed. The real infrastructure resource stays in place.
Expected use cases include handing off log-storage buckets to another tool or manual operations, putting back into unmanaged state any temporary resources that were Terraform-managed only during validation, and removing entries from state in a team-reviewable fashion.
removed is a top-level block. In from, you specify “the address of the object that was previously managed.” count/for_each instances are supported via index/key specifications. At plan time, Terraform interprets the relevant state entry as a “state removal” rather than a destroy.
In terms of apply ordering, removed is processed as part of the normal diff resolution. If the target does not exist in state, nothing happens. After apply, you may delete the removed block itself from your code (it is a temporary declaration meant for migration).
Plan and apply flow with removed
removed is the tool for “taking a resource out of management.” Use moved for rename and address changes, terraform state rm for an immediate local-only state edit, and destroy when you actually want to delete the real infrastructure. This distinction is also a frequent exam topic.
In particular, note that merely deleting a resource definition from code schedules a destroy. Use removed in combination when you want to suppress destroy and forget the resource from state.
| Approach | Primary Purpose | Effect on Real Infrastructure | Declarative / Review Fit |
|---|---|---|---|
| removed block | Removes from management (forgets from state) | Not deleted (resource remains) | High (can stay in code) |
| moved block | Change resource/module address | Not deleted (resource preserved) | High (trackable in code) |
| terraform state rm | Manually delete from state | Not deleted (resource remains) | Low (ad-hoc command; weak reproducibility and reviewability) |
| terraform destroy / -target | Delete the real resource | Deleted (provider destroy) | Medium (plan is visible but not retained as a declaration) |
As an example, suppose aws_s3_bucket.logs (an audit log bucket) will from now on be managed directly by the security team. You want to remove it from Terraform’s scope but keep the actual bucket. Simply deleting it from code schedules a destroy, so you use removed.
After apply, the bucket disappears from state and subsequent plans no longer reference it from Terraform. If other resources reference it, first switch those references (to data sources, external inputs, variables, etc.) before applying.
HCL example: take an S3 bucket out of management
# Assumes Terraform >= 1.6
# Existing: aws_s3_bucket.logs is present in state
terraform {
required_version = ">= 1.6.0"
}
# Previously this file defined aws_s3_bucket.logs but it has been removed
# We want to drop it from state without destroying it
removed {
from = "aws_s3_bucket.logs"
}
# Example of removing a specific count/for_each instance
# removed {
# from = "aws_iam_user.legacy[\"temp\"]"
# }
Watch the order in which dependencies are resolved. If other resources reference the target of removed, plan fails due to a broken reference. Replace the references first (switch to data sources, external inputs, or avoid hardcoding) or split the apply into phases.
To preserve state consistency, the safe practice is to include removed in a PR, get it reviewed, confirm a no-op after apply, and then delete the removed block. If you also use CLI state rm, retain an audit log and runbook of who did what and when.
You are expected to clearly articulate the difference between removed and moved, and how they differ from destroy. In scenario questions, read “keep the real resource,” “take it out of management,” and “change the address” as cues, then pick the right block or command.
Other common topics include specifying individual count/for_each instances, the fact that removed is a temporary declaration that can be deleted from code after apply, and that team operations should prefer declarative approaches (removed/moved).
Pro
問題 1
A team has changed policy so that an existing audit-log S3 bucket will from now on be managed manually by the security department. The bucket must not be deleted. The bucket definition has already been removed from the Terraform code, and the current plan proposes a destroy. Which is the most appropriate action?
正解: A
The requirement is to “take it out of Terraform management without deleting it.” removed forgets the resource from state without performing destroy, so it fits. moved is for address changes, destroy actually deletes it, and ignore_changes only ignores configuration diffs and does not remove from state.
Can removed be used on data resources?
Generally, removed targets instances of managed resources. Data sources do not create real infrastructure and are not tracked in state as managed objects, so removed normally does not apply to them.
Is it okay to keep removed in the code permanently?
It is recommended to delete it once apply has completed and you have confirmed a no-op. removed is a temporary declaration for migration and does not need to stay in the code.
What happens if I write both moved and removed for the same address?
The semantics conflict. Pick either an address change (moved) or de-management (removed). If staged migration is required, first align addresses with moved, then unmanage a different resource with removed; split the plan into phases.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
HCL Syntax: Terraform's Configuration Language (2026)
HCL2 fundamentals for Terraform — blocks, attributes, expres...
Terraform Authoring & Operations Pro: Complete Guide (2026)
Tactics for the Terraform Pro exam — module authoring, works...
Terraform Providers: Plugin Management Fundamentals (2026)
Provider mechanics — required_providers, versions, mirrors, ...
Terraform Resource Blocks: Declarative Infra Units (2026)
Resource block fundamentals — addresses, references, common ...
Terraform Data Sources: Read-Only External Data (2026)
Data source basics — declaration, refresh behavior, dependen...