A rename between two types
Terraform rejects it: the stored attributes belong to the old schema
aws_instance.a -> aws_db_instance.a
Turn a list of renames into moved blocks. Write one old and one new address per line, separated by an arrow, a comma or a space.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Generate. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
Terraform rejects it: the stored attributes belong to the old schema
aws_instance.a -> aws_db_instance.a
A cycle has no end state, so it needs a temporary name and two applies
aws_instance.a -> aws_instance.b aws_instance.b -> aws_instance.a
The module move already covers them, so the extra lines only hide it
module.old -> module.new module.old.aws_instance.web -> module.new.aws_instance.web
These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
Any environment that has not applied yet still has the old address. Its next apply sees an object with no matching configuration and destroys it.
Instead:Keep them until every workspace and environment has applied once. Leaving them permanently costs nothing but reading.
The attributes in state belong to the old schema. Terraform rejects the move rather than attempting a conversion.
Instead:Remove the old resource from state and import the object as the new type.
The module-level move already covers everything inside it, so the extra blocks do nothing and hide the single line that matters in the diff.
Instead:Write moved from module.old to module.new and delete the rest.
That framing explains every rule below, including the one that catches people out: when it is safe to delete the block again.
The block exists to tell a state with the old address about the new one. Delete it before some workspace or some environment has applied it, and that state still holds the old address, which the configuration no longer contains, so the next apply destroys the object and creates a fresh one. Leave them in for a full pass through every environment.
Terraform matches state to configuration by address, and it has no way to tell a rename from a deletion plus an addition. This is why renaming a resource for tidiness is not a cosmetic change.
aws_instance.a to aws_db_instance.a cannot work. The stored attributes belong to the old type's schema and mean nothing to the new one, so Terraform refuses rather than trying and failing halfway. That case needs a state removal and an import, not a move.
a to b and b to c resolves in one apply, and that is exactly what accumulates when something is renamed twice over two releases. Two resources swapping names is a cycle, which has no end state and is rejected: it needs a temporary third name and two applies.
moved from module.old to module.new moves everything inside it. Writing a block per resource as well is harmless and buries the one line that matters, which makes the change harder to review than it needs to be.
Both addresses are in the same state. Moving an object into another configuration's state is terraform state mv with -state-out, or a removed block plus an import. A moved block pointing at an address in a different state does nothing useful.