Recovering from a Botched Terraform Apply That Left State Half-Updated
You ran terraform apply, something went wrong halfway through, and now your state file is a lie. Some resources got created, some didn't, and Terraform thinks it knows what exists β but it doesn't. This is a genuinely stressful situation, and the instinct to just run apply again and hope for the best is the wrong one.
This guide walks you through how to assess the damage, stabilize your state, and get back to a clean baseline without making things worse.
What you'll learn
- How to figure out exactly what went wrong and what state is corrupted
- How to use
terraform refresh,terraform statecommands, andterraform importto reconcile drift - When it's safe to re-run apply and when it isn't
- How to protect yourself from this happening again
Prerequisites
This guide assumes you're running Terraform 1.x and have CLI access to your cloud provider (AWS, GCP, DigitalOcean, or similar). You should be comfortable reading a terraform plan output and have basic familiarity with the HCL syntax. Remote state (S3, Terraform Cloud, etc.) is assumed but local state applies too.
Understand What Actually Happened
Before touching anything, read the error output carefully. Terraform applies resources in dependency order and stops when it hits a hard error. The resources that were already applied are written to state. The ones that hadn't started are not. The ones mid-flight depend on where exactly the failure occurred.
Run this first:
terraform planRead the output like a diagnostic, not a to-do list. You're looking for three things: what Terraform believes currently exists (its state), what it wants to change, and whether any of those planned changes look wrong given what you know actually exists in the cloud console.
Open your cloud provider's console or use the CLI to manually inspect the resources in question. Compare what you see there against what terraform show reports. Discrepancies are your problem areas.
Back Up Your State File First
Before running any command that modifies state, make a copy. This is non-negotiable.
If you're using S3 as a backend, grab a snapshot:
aws s3 cp s3://your-bucket/path/to/terraform.tfstate ./terraform.tfstate.backup-$(date +%Y%m%d%H%M%S)If you're using local state:
cp terraform.tfstate terraform.tfstate.backup-$(date +%Y%m%d%H%M%S)If you're on Terraform Cloud, the UI keeps state version history automatically, so you can roll back from there. Still, note the current version ID before doing anything.
Refresh State to Reflect Reality
The terraform refresh command (or terraform apply -refresh-only in newer versions) queries your cloud provider's actual API and updates the state file to match what's really there. It does not make any infrastructure changes.
# Terraform 1.x preferred approach
terraform apply -refresh-onlyThis is a safe first step in most cases. It will pull in the actual attributes of existing resources and correct any stale values. After running it, do another terraform plan and see if the discrepancies narrow.
One caveat: if a resource was partially created (e.g., an AWS RDS instance that started provisioning but never completed), the refresh might not find it at all, or it might find it in a broken state. You'll need to handle those manually.
Deal with Resources That Exist in Cloud but Not in State
Sometimes Terraform created a resource successfully but crashed before writing it to state. The resource is real, but Terraform has no record of it. If you run apply now, Terraform will try to create it again, and you'll get a duplicate or a conflict error.
The fix is terraform import. This tells Terraform:
π€ Share this article
Sign in to saveRelated Articles
Comments (0)
No comments yet. Be the first!