TerraformPilot

DevOps

Fix Terraform Error: Instance Not Found After External Deletion

Fix terraform instance not found errors when resources are deleted outside of Terraform. Covers state refresh, state rm, drift detection, import

LLuca Berton1 min read

Quick Answer

#
# Terraform auto-detects the deletion — just plan and apply
terraform plan    # Shows: "read during apply" or "will be created"
terraform apply   # Recreates the missing resource

The Error

#
Error: reading EC2 Instance (i-0abc123def456): couldn't find resource
 
Error: error reading S3 Bucket (my-bucket): NoSuchBucket: The specified bucket does not exist
 
Warning: Value for undeclared variable — The resource aws_instance.web no longer exists

Or during refresh:

aws_instance.web: Refreshing state... [id=i-0abc123def456]
aws_instance.web: Resource not found, removing from state

What Causes This

#

Someone (or something) deleted the resource outside of Terraform:

  • Deleted via AWS Console manually
  • Deleted by another automation tool (CloudFormation, Ansible, scripts)
  • Auto-scaling terminated the instance
  • AWS terminated a spot instance
  • Account cleanup or organization policies

Solution 1: Let Terraform Recreate It

#
# Terraform detects the deletion during refresh
terraform plan
# aws_instance.web has been deleted
- resource "aws_instance" "web" {
    - id = "i-0abc123def456"
    ...
  }
 
# aws_instance.web will be created
+ resource "aws_instance" "web" {
    + id = (known after apply)
    ...
  }
terraform apply   # Recreates the resource

This is the cleanest fix — Terraform handles it automatically.

Solution 2: Remove from State (Don't Recreate)

#

If you don't want the resource anymore:

# Remove the resource from Terraform state
terraform state rm aws_instance.web
 
# Now remove the resource block from your .tf files
# Then plan to verify
terraform plan

Solution 3: Import a Replacement

#

If someone recreated the resource with a different ID:

# Import the new resource
terraform import aws_instance.web i-0newid789
 
# Or use import block (Terraform 1.5+)
import {
  to = aws_instance.web
  id = "i-0newid789"
}

Solution 4: Refresh-Only Plan

#

Detect all drift without making changes:

terraform plan -refresh-only
Note: Objects have changed outside of Terraform
 
Terraform detected the following changes made outside of Terraform:
 
  # aws_instance.web has been deleted
  - resource "aws_instance" "web" { ... }
 
  # aws_security_group.web has been changed
  ~ resource "aws_security_group" "web" {
      ~ ingress = [
          + { from_port = 3389, ... }  # Someone added RDP access
        ]
    }

Apply the refresh to update state without changing infrastructure:

terraform apply -refresh-only

Prevention: Protect Critical Resources

#

Terraform Lifecycle

#
resource "aws_db_instance" "main" {
  # ...
  lifecycle {
    prevent_destroy = true
  }
}

This prevents terraform destroy from deleting it, but doesn't protect against console deletion.

AWS Termination Protection

#
resource "aws_instance" "critical" {
  instance_type           = "t3.large"
  disable_api_termination = true   # Can't delete via API/console
 
  tags = {
    Name = "critical-service"
  }
}
 
resource "aws_db_instance" "main" {
  deletion_protection = true   # RDS deletion protection
}
 
resource "aws_s3_bucket" "important" {
  # Use object lock or bucket policy to prevent deletion
}

Drift Detection in CI/CD

#
# Nightly drift detection
drift-check:
  stage: monitor
  script:
    - terraform init
    - terraform plan -refresh-only -detailed-exitcode
    # Exit code 2 = drift detected
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"
  allow_failure: true

-detailed-exitcode returns:

  • 0 — no changes
  • 1 — error
  • 2 — changes detected (drift)

Hands-On Courses

#

Conclusion

#

When resources are deleted outside Terraform, just run terraform plan — it detects the deletion and offers to recreate. Use terraform state rm if you don't want it back, or terraform import if it was replaced. Prevent drift with disable_api_termination, deletion_protection, and nightly terraform plan -refresh-only in CI.

#Terraform#Troubleshooting#DevOps#Error Fix#Infrastructure as Code

Share this article