Terraform · Infrastructure as code

How do moved blocks prevent unnecessary destruction during refactors?

Hardrefactoringmoved blocksstateUpdated Oct 2026
Quiz this track

Short answer

A moved block tells Terraform that a resource or module changed address, so it updates state instead of destroying and recreating. Use it for renames and module restructuring, and keep it until all environments have applied.

Terraform identifies resources by address. Renaming a block, moving it into a module or changing count to for_each changes that address. Without a hint, Terraform plans a destroy and create. A moved block records the old and new addresses so the state entry is rewritten.

hcl
moved {
  from = aws_instance.web
  to   = aws_instance.app
}

moved {
  from = module.network
  to   = module.vpc
}
The blocks are declarative and can be reviewed with the refactor that caused the address change.

When to use moved

  • Renaming a resource or data source within a module
  • Moving a resource into or out of a child module
  • Changing count to for_each while preserving each instance
  • Renaming a module call in the root module

Keep the moved block until every environment that shares the configuration has applied the refactor. Removing it too early means an environment that has not applied will see the old address as deleted and the new one as created. For instance-level moves, list one block per address or use terraform state mv in a controlled migration.

A moved block changes bookkeeping only. If the underlying resource type or provider schema also changed, you may still need a real replacement.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1What happens if you rename a resource without a moved block?
  2. 2When is it safe to delete a moved block?
  3. 3How do you move one instance from count to for_each?
  4. 4Does moved work across modules?

Say it in the interview

Terraform tracks resources by address, so a rename or module move looks like a destroy and create. A moved block maps the old address to the new one and rewrites state instead. I keep it until every environment has applied the refactor, then remove it in a later change. For per-instance moves I use one block per address or a controlled state mv.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Terraform mock interview and get scored feedback on depth, clarity and confidence.