A resource already exists, but its Terraform configuration needs to change. Should you import it, move it, or remove it? The answer depends on what Terraform already manages and what should remain under management afterward. The same-looking cloud resource can require a different operation in a different state.
Describe the intended binding first
| Intent | Starting point | Block to consider |
|---|---|---|
| Adopt an existing object | The object exists but is not bound to this resource address in state | import |
| Rename or reorganize a managed object | State already tracks it at an old address | moved |
| Stop managing an object but retain it | State tracks it, but ownership is being handed off | removed with destroy = false |
State records which remote object is associated with each managed resource instance. Before making a change, establish the backend, workspace, provider account, and current resource address. A correct block against the wrong state can still be the wrong operation. Do not manually edit the state JSON to make an unexpected plan look smaller.
Use import to adopt an existing object
A configuration-driven import identifies an existing object and the Terraform address that should manage it. The resource type's provider documentation defines its import identifier. You also need the corresponding resource configuration, whether you write it or use supported configuration generation and review the result.
import {
to = aws_s3_bucket.logs
id = "replace-with-existing-bucket-name"
}
This example assumes the AWS provider's S3 bucket import identifier, an existing bucket, and an appropriate aws_s3_bucket.logs resource declaration. It is not a complete configuration. Importing the object does not mean every configured attribute already matches it: inspect the plan for additional changes rather than treating adoption as automatically change-free.
Before approval, write down the real object, its intended address, and the team that owns it. Check whether another state already manages it. A handover needs coordination; importing an object into a second configuration is not a substitute for agreeing which configuration is authoritative.
Use moved to preserve identity during a refactor
Suppose the existing address is aws_s3_bucket.logs and the configuration now calls it aws_s3_bucket.audit_logs. A moved block records that address transition, allowing Terraform to associate the existing object with the new name rather than interpreting the rename as an unrelated removal and creation.
moved {
from = aws_s3_bucket.logs
to = aws_s3_bucket.audit_logs
}
Update the resource declaration and references consistently. A move is not a promise that no other changes will occur: attribute changes in the same revision may still propose updates or replacement. Review those separately. For reusable modules, retaining earlier moved blocks can preserve upgrade paths for users who have not yet applied an intermediate version.
Use removed carefully when handing off ownership
Deleting a resource declaration is not a safe shorthand for 'leave the object alone'. For an intentional handoff, a removed block can explicitly tell Terraform to stop managing the object without destroying it. The lifecycle setting matters because removal otherwise defaults to destruction.
removed {
from = aws_s3_bucket.legacy_logs
lifecycle {
destroy = false
}
}
In this separate example, replace the old resource declaration with the removed block and resolve references that depended on it. Review the plan for the intended management removal. The retained object still needs an owner, access controls, monitoring, and a cost decision. Leaving Terraform state is not equivalent to retiring the service.
Review the transition, not just the block name
- Before: identify the real object and whether this state already manages it.
- After: state the desired address or the new management owner.
- Proposal: inspect the plan for imports, address moves, removals, and unrelated infrastructure changes.
- Evidence: record the provider's import rules or the relevant language behavior alongside the change.
- Handoff: confirm who approves the change and who owns the object afterward.
For study, try three variations of one scenario: the object was created manually; the object is already managed under an older name; or another team is taking over management. Explain the difference without first naming a command. Then identify what evidence is missing before any change could be approved.
If the plan disagrees with that explanation, stop and use the unexpected Terraform plan checklist. Keep state and plan artifacts out of public repositories and support threads. The Terraform Associate study guide connects these state decisions to the wider workflow.