Sooner or later you will need to move, remove or import state. Here's the runbook we use so it doesn't become an incident.
State surgery has an unfortunate reputation, mostly because it is usually done under pressure by someone who has not done it before. The operations themselves are safe. The context they are performed in is what causes damage.
Before touching anything
- Take a copy of the state and confirm you can read it back — versioned backends make this trivial and it takes thirty seconds
- Run a plan and save the output, so you have a documented before-state to compare against
- Announce a freeze on the workspace; a concurrent apply mid-surgery is the actual disaster scenario
- Write the exact commands out first and have someone read them back to you
The operations
Use moved blocks rather than terraform state mv wherever possible — they are declarative, reviewable in a pull request, and leave an audit trail in the repository. Reserve imperative state commands for cases the block syntax cannot express, and script them so the change is repeatable in every environment rather than hand-typed per workspace.
Afterwards
A plan that shows no changes is the only acceptable end state. If it shows a destroy, stop and restore the backup rather than applying and hoping. The most expensive Terraform incidents we have been called into all share one line in the timeline: somebody applied a plan they had not read.