Explain `terraform state mv`, `terraform state rm`, and `terraform import`.
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.