Rename a Terraform resource without a destroy/recreate — complete the moved block
You renamed a resource from aws_instance.web to aws_instance.app in your config. A plain plan now wants to destroy web and create app — a needless replacement of a live server. Refactor it so Terraform treats this as a rename, with zero destroy/recreate, using a moved block (no manual terraform state mv).
Constraints:
- The resource block is already renamed to
aws_instance.app. - Use a
movedblock so the rename is code-reviewable and repeatable in CI. - After
apply,planmust show no changes.
resource "aws_instance" "app" {
ami = "ami-123"
instance_type = "t3.small"
}
# Add the block that tells Terraform "app" is the renamed "web".
Complete the refactor.
Add a moved block mapping the old address aws_instance.web to the new aws_instance.app. On the next plan Terraform rewrites the state address in place, so nothing is destroyed or created. It is declarative and reviewable, unlike a one-off terraform state mv.
- ✗Assuming a plain rename is matched by attributes, not by address
- ✗Reaching for
terraform state mvinstead of a reviewablemovedblock - ✗Thinking
prevent_destroyperforms the rename
- →When is a one-off
terraform state mvstill the right tool overmoved? - →How do
movedblocks help when refactoring resources into a module?
moved declares that the new address is the renamed old one. Terraform rewrites the state address in place instead of treating them as unrelated resources.
resource "aws_instance" "app" {
ami = "ami-123"
instance_type = "t3.small"
}
moved {
from = aws_instance.web
to = aws_instance.app
}
After apply, the next plan reports "No changes". The block can be removed once the refactor has rolled out everywhere. Unlike terraform state mv, it is visible in code review and runs identically in CI.