Explain `terraform state mv`, `terraform state rm`, and `terraform import`.

5 minadvancedterraformstateimportcli

Quick Answer

`terraform state mv` renames a resource's address in state (e.g., after refactoring code) without destroying/recreating the underlying infrastructure. `terraform state rm` removes a resource from state *without* destroying the real object — Terraform simply forgets about it (useful before deleting a resource block you want to keep externally). `terraform import` does the reverse: it brings an existing, unmanaged resource under Terraform's management by associating a real object's ID with a resource address already written in configuration. All three are state "surgery" commands that avoid unwanted destroy/recreate cycles.

Detailed Answer

These three commands all manipulate the mapping between configuration and real infrastructure without necessarily touching the real infrastructure itself — they're the toolkit for when state and configuration need to be reconciled deliberately.

terraform state mv

Renames or moves a resource's address in state without destroying/recreating it.

terraform state mv aws_instance.web aws_instance.web_server

Common scenario: you refactor configuration (rename a resource, move it into a module) and want Terraform to understand "this is the same real object, just under a new address" — without this, Terraform would plan to destroy the old address and create a new one under the new address.

terraform state rm

Removes a resource from state without touching the real object.

terraform state rm aws_instance.legacy

Terraform simply "forgets" the resource — the EC2 instance keeps running, but Terraform no longer manages or tracks it. Useful when you're deliberately handing a resource off to be managed manually or by a different tool/team, or need to remove a broken state entry.

terraform import

The reverse operation: bring an existing, unmanaged real-world object under Terraform's management.

terraform import aws_instance.web i-0abcdef1234567890

This requires a matching resource "aws_instance" "web" { ... } block already written in configuration (import only populates state — it doesn't generate .tf code for you, though terraform plan -generate-config-out in newer versions can help scaffold it). After import, Terraform treats that resource as fully managed going forward.

Why these matter

All three exist to avoid unwanted destroy-and-recreate cycles that would otherwise happen if configuration and state addresses don't line up exactly. They're "state surgery" — precise, deliberate operations rather than something you'd run casually; a mistake with state rm followed by re-applying can cause Terraform to try to create a duplicate of something that already exists.

Related Resources