Skip to main content
In this lesson we cover Terraform’s moved block — the safe, declarative way to tell Terraform that a resource address has changed (for example, because you renamed a resource or moved it into a module) so the state can be updated without destroying or recreating infrastructure. Why this matters
  • Early in a project you may use simple names like vpc and vpc1. Later you want clearer names (for example, sbx_vpc and test_vpc). If you rename a resource in code without telling Terraform, Terraform will interpret the rename as the old address being removed and a new one added — causing a planned destroy and recreate.
  • Similarly, refactoring a root module into child modules (e.g. splitting network, security, compute) changes resource addresses. Terraform treats aws_instance.web_server and module.compute.aws_instance.web_server as different addresses. Without informing Terraform about the address changes, it will attempt destructive changes.
Example: two VPCs created early in the project
If you rename the sandbox resource in code to sbx_vpc but do not map the old address to the new address in state, Terraform will plan to destroy aws_vpc.vpc and create aws_vpc.sbx_vpc:
Example terraform plan output you might see if you do not map the old address to the new one:
That planned destroy would affect anything depending on that VPC (subnets, route tables, EC2 instances, etc.). If your intent was only to rename the resource in code, you need a way to inform Terraform to keep the same physical resource but update its address in the state. The moved block solves exactly that.
A colorful diagram titled "Another Scenario..." showing grouped boxes for cloud infrastructure components — Security, Database, Network, DNS, Load Balancing, Apps, and Compute — with colored blocks labeled Firewall, FW Rule, Database, Subnet, DNS, VM, etc. It appears to be an architecture/deployment blueprint (Terraform logo in the top right).
What the moved block does
  • It instructs Terraform to reassign an existing state entry from one address (from) to a new address (to) when you run terraform apply.
  • No provider API calls are made for the resource being moved — Terraform updates only the state metadata.
  • Use it for renames, relocating resources into modules, or renaming/moving entire modules.
Common use cases
A presentation slide titled "Moved Block" with explanatory text and a purple dolly icon on the right. On the left is a framed photo of a purple upward arrow painted on a concrete surface.
Syntax and examples Each moved block contains from and to, both string resource addresses. Make sure the destination address exists in configuration before you run terraform plan or terraform apply. Example usages:
Behavior notes
  • After applying a moved block, Terraform updates the state so the new address tracks the existing infrastructure previously tracked at the from address.
  • There are no provider API calls for the moved resources; the change is purely a state address update.
  • The moved block is evaluated during planning and applied as a fast internal state operation.
Refactoring workflow (recommended sequence)
  1. Add the new resource blocks or create the destination module in your Terraform configuration so Terraform can see the destination addresses.
  2. Add moved blocks mapping each old address to its new address in the same configuration.
  3. Run terraform plan to validate the mapping. The plan should indicate zero creates/destroys for the moved resources and show state move messages.
  4. Run terraform apply to perform the state updates. This changes only the state entries — no provider-level changes occur.
  5. After you confirm state has been updated, optionally remove the moved blocks. Some teams keep them in a moved.tf file for record-keeping; they are not required permanently.
A slide showing "The Refactoring Workflow" as a step-by-step diagram for moving Terraform configuration: Write → Write → Plan → Apply → Delete, with icons and brief notes about adding resource/moved blocks, running terraform plan and apply, then deleting the moved blocks.
Before applying, always ensure the destination resource or module exists in configuration. If the to address is missing, Terraform cannot map the state and may attempt destructive changes.
moved blocks are temporary scaffolding for refactoring. After a successful terraform apply you can remove them (or keep them for documentation).
Best practices and tips
  • Validate with terraform plan first and inspect messages about state moves.
  • Keep a record (e.g. moved.tf) of the refactor in VCS so other team members understand address changes.
  • Use explicit module addresses in moved blocks to avoid ambiguity (e.g. module.my_module.aws_resource.name).
  • For large refactors, map multiple resources in one moved block per resource pair (each resource gets its own moved block).
Links and references Using moved blocks lets you refactor names and module structure safely: no downtime, no manual state editing, and no unexpected infrastructure replacements — just clean, declarative refactoring.

Watch Video