Terraform Refactoring · Terraform systems note
Terraform moved Blocks Are Migration History, Not Cleanup Noise
A moved block records that a resource address changed while the remote object did not. Removing it too early can make older module consumers see a destructive refactor.
Renaming a Terraform resource changes its address, even when the remote object should remain unchanged. Without migration information, Terraform can see the old address disappear and a new one appear.
moved blocks preserve object identity
moved {
from = aws_instance.web
to = aws_instance.app
}Terraform checks state for the old address, re-associates the object with the new address, then plans from there.
Migration belongs with the module
For shared modules, a moved block is better than telling every consumer to run state mv. Dev, staging and production can all upgrade through the same declared migration.
Removing it can be breaking
A workspace that skips intermediate module versions may still carry the old address. HashiCorp explicitly treats removal of moved history as a compatibility decision.
Plan the refactor like a schema migration
Review every moved instance, ensure preserved resources show address changes rather than destroy/create, and keep migration blocks until you intentionally drop compatibility with older state layouts.