Moved blocks
A moved block tells Terraform that a resource has a new address in your configuration. Without it, renaming a resource or moving it into a module makes Terraform plan to destroy the object at the old address and create a new one at the new address. A moved block updates the state instead, leaving the real infrastructure untouched.
flowchart LR
old["random_pet.server"] -- "moved block<br/>(state only, no destroy)" --> new["random_pet.web_server"]
Say you want to rename a resource:
main.tf
| |
Rename the resource and add a moved block with the old address in from and the new address in to:
main.tf
| |
Terraform confirms in the plan that nothing will be recreated:
random_pet.web_server: Refreshing state... [id=neat-alpaca]
Plan: 0 to add, 0 to change, 0 to destroy.Moved blocks also handle refactoring a resource into a module:
main.tf
| |
…and switching from count to for_each:
main.tf
| |
Best practices
- Add a moved block whenever you rename a resource, move it into or out of a module, or change its
count/for_eachkeys — never let Terraform destroy and recreate an object just because of a refactoring. - Always check the plan says
0 to destroyafter a refactoring. - Keep moved blocks in place for a release or two if others consume your modules, so their state migrates too — then clean them up.