Terraform moved Block Generator

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.

Paste below, or drop a file anywhere on this panel

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.

Examples

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.

A rename between two types

Terraform rejects it: the stored attributes belong to the old schema

aws_instance.a -> aws_db_instance.a

Two resources swapping names

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

A module rename with the resources listed too

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

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Removing the moved blocks in the commit after the rename

    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.

  2. Using a moved block to change a resource's type

    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.

  3. Writing one moved block per resource when renaming a module

    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.

A moved block is instructions for a state that has not caught up

That framing explains every rule below, including the one that catches people out: when it is safe to delete the block again.

Deleting a moved block too early undoes it

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.

A rename with no moved block is a destroy and a create

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.

Moving between resource types is rejected

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 chain is fine and a cycle is not

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.

Renaming a module is one block, not one per resource

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.

moved cannot cross state files

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.

More terraform tools

Terraform Validator & Formatter Does it parse, and is it formatted? Terraform dynamic Block Generator It is ingress.value, not each.value Terraform check and precondition Generator A failed check does not stop the apply Terraform variables.tf Generator From the var. references you already wrote Terraform Unused Declaration Linter Dead variables, locals and data sources Terraform Atlantis YAML Generator when_modified misses your modules Terraform Function Tester and HCL Console terraform console, in a tab Terraform for Expression Tester Where do the keys collide? Terraform Interpolation Tester null becomes an empty string Terraform templatefile Tester Render it before you apply it Terraform Resource Count Calculator How many objects, not how many blocks Terraform count to for_each Converter With the moved blocks it needs Terraform state mv Command Builder No plan, no undo Terraform target Flag Builder And why to stop using it Terraform outputs.tf Generator Outputs are not sensitive by default Terraform Remote State Data Source Generator It grants read of the whole state Terraform Provider Block Generator docker is not hashicorp/docker Terraform .gitignore Generator and Checker .terraform* eats the lock file Terraform to OpenTofu Migration Checker The state is the part to watch Terraform tfvars to JSON Converter The JSON file wins Terraform Version Constraint Parser What ~> actually allows Terraform Resource Address Parser Quote it before the shell eats it Terraform cidrsubnet Calculator newbits is added, not the target Terraform Import Block Generator The id is not the name Terraform Lock File Viewer Why CI fails and your laptop does not Terraform Variables Checker A missing value hangs CI Terraform tfvars to Env Vars Converter Lists and maps have to be JSON Terraform Deprecated Syntax Checker What a current Terraform rejects Terraform State File Viewer Read it without uploading it Terraform Plan JSON Viewer It is not redacted Terraform HCL to JSON Converter And what the conversion loses Terraform Module Source Validator version only works for the registry Terraform Backend Config Decoder Is state actually locked? Terraform Naming Convention Validator A hyphen makes a resource unreferenceable

Elsewhere on the site