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