<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Terraform State Recovery on AWS: Simulating State Loss, Importing Resources, and Detecting Drift]]></title><description><![CDATA[Terraform State Recovery on AWS: Simulating State Loss, Importing Resources, and Detecting Drift]]></description><link>https://fourasignment.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 02 Nov 2026 23:52:11 GMT</lastBuildDate><atom:link href="https://fourasignment.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Terraform State Recovery on AWS: Simulating State Loss, Importing Resources, and Detecting Drift]]></title><description><![CDATA[Github repo: Terraform is powerful because it allows infrastructure to be managed as code. But behind every Terraform project, there is one very important…]]></description><link>https://fourasignment.hashnode.dev/terraform-state-recovery-on-aws-simulating-state-loss-importing-resources-and-detecting-drift</link><guid isPermaLink="true">https://fourasignment.hashnode.dev/terraform-state-recovery-on-aws-simulating-state-loss-importing-resources-and-detecting-drift</guid><dc:creator><![CDATA[Muhammad Hashim]]></dc:creator><pubDate>Fri, 01 May 2026 16:13:29 GMT</pubDate><content:encoded><![CDATA[<p><strong>Github repo:</strong> <a href="https://github.com/HashimZaffar/Asignment-4">https://github.com/HashimZaffar/Asignment-4</a></p>
<p>Terraform is powerful because it allows infrastructure to be managed as code. But behind every Terraform project, there is one very important file that many beginners do not fully understand at first: the <strong>Terraform state file</strong>.</p>
<p>In this assignment, I built a practical Terraform State Recovery project on AWS. The goal was to simulate accidental state deletion, recover existing infrastructure using <code>terraform import</code>, and detect drift when someone makes manual changes outside Terraform.</p>
<p>This is an important DevOps skill because real-world infrastructure work is not only about creating resources. It is also about recovering from mistakes, troubleshooting state issues, and keeping infrastructure aligned with code.</p>
<h2>Project Objective</h2>
<p>The objective of this assignment was to simulate a realistic Terraform recovery scenario.</p>
<p>The project covered:</p>
<pre><code class="language-text">Accidental deletion of Terraform state
Recovery using terraform import
Drift detection using terraform plan
Drift correction
Remote backend best practices
S3 state storage
DynamoDB state locking
</code></pre>
<p>The infrastructure used for this demo was simple but practical:</p>
<pre><code class="language-text">AWS VPC
Public subnet
Security group
</code></pre>
<p>The focus was not on building a large architecture. The focus was on understanding how Terraform remembers infrastructure and how to recover that memory if it is lost.</p>
<h2>What is Terraform State?</h2>
<p>Terraform state is Terraform’s memory.</p>
<p>When Terraform creates a resource in AWS, it records that resource in a state file. For example, if Terraform creates a VPC, subnet, or security group, Terraform stores the real AWS resource IDs inside the state file.</p>
<p>Without state, Terraform does not know what it already created.</p>
<p>For example, if AWS still has a VPC but Terraform state is missing, Terraform may think the VPC does not exist and try to create it again.</p>
<p>That is why Terraform state is one of the most important parts of Infrastructure as Code.</p>
<h2>Why State Recovery Matters</h2>
<p>In real DevOps work, state issues can happen because of:</p>
<pre><code class="language-text">Accidental deletion
Incorrect backend migration
Manual file removal
Broken CI/CD pipeline
Wrong workspace or backend
S3 object deletion
Team members running Terraform from different places
</code></pre>
<p>If state is lost, the infrastructure may still exist in AWS, but Terraform no longer tracks it.</p>
<p>This creates a dangerous situation:</p>
<pre><code class="language-text">AWS resources exist
Terraform does not know about them
Future plans may try to recreate or change resources incorrectly
</code></pre>
<p>State recovery is the process of reconnecting Terraform code with existing infrastructure.</p>
<h2>Project Setup</h2>
<p>The project started with a new Git repository:</p>
<pre><code class="language-bash">mkdir Asignment-4
cd Asignment-4
git init
</code></pre>
<p>The folder structure was simple:</p>
<pre><code class="language-text">Asignment-4/
└── environments/
    └── dev/
        ├── provider.tf
        ├── main.tf
        ├── variables.tf
        ├── terraform.tfvars
        ├── outputs.tf
        └── recovery-notes.md
</code></pre>
<p>This structure keeps the dev environment separate and makes the project easy to understand.</p>
<h2>Terraform Provider Configuration</h2>
<p>The provider file defines Terraform version requirements and the AWS provider.</p>
<pre><code class="language-hcl">terraform {
  required_version = "&gt;= 1.6.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~&gt; 6.0"
    }
  }
}

provider "aws" {
  region = var.aws_region

  default_tags {
    tags = var.common_tags
  }
}
</code></pre>
<p>This configuration tells Terraform to use AWS as the cloud provider and to apply common tags to supported resources.</p>
<p>The use of variables keeps the code flexible. Instead of hardcoding the region, the region is provided through <code>terraform.tfvars</code>.</p>
<h2>Infrastructure Code</h2>
<p>The project creates three AWS resources:</p>
<pre><code class="language-text">VPC
Public subnet
Security group
</code></pre>
<p>Example VPC resource:</p>
<pre><code class="language-hcl">resource "aws_vpc" "recovery_demo" {
  cidr_block           = var.vpc_cidr
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "${var.environment}-state-recovery-vpc"
  }
}
</code></pre>
<p>This creates a VPC with DNS support and a clear name tag.</p>
<p>The subnet is created inside the VPC:</p>
<pre><code class="language-hcl">resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.recovery_demo.id
  cidr_block              = var.public_subnet_cidr
  availability_zone       = var.availability_zone
  map_public_ip_on_launch = true

  tags = {
    Name = "${var.environment}-state-recovery-public-subnet"
  }
}
</code></pre>
<p>The important line here is:</p>
<pre><code class="language-hcl">vpc_id = aws_vpc.recovery_demo.id
</code></pre>
<p>This tells Terraform that the subnet belongs to the VPC created above.</p>
<p>The security group allows HTTP traffic for demo purposes:</p>
<pre><code class="language-hcl">resource "aws_security_group" "web_sg" {
  name        = "${var.environment}-state-recovery-web-sg"
  description = "Security group for Terraform state recovery demo"
  vpc_id      = aws_vpc.recovery_demo.id

  ingress {
    description = "Allow HTTP traffic for demo"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = var.http_allowed_cidrs
  }

  egress {
    description = "Allow all outbound traffic"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.environment}-state-recovery-web-sg"
  }
}
</code></pre>
<p>This security group is used to demonstrate how Terraform tracks AWS resources in state.</p>
<h2>Variable Values</h2>
<p>The actual values are stored in <code>terraform.tfvars</code>.</p>
<pre><code class="language-hcl">aws_region         = "us-east-1"
environment        = "dev"
vpc_cidr           = "10.60.0.0/16"
public_subnet_cidr = "10.60.1.0/24"
availability_zone  = "us-east-1a"
http_allowed_cidrs = ["0.0.0.0/0"]

common_tags = {
  Project     = "Asignment-4"
  Environment = "dev"
  Owner       = "Hashim."
  ManagedBy   = "Terraform"
  Purpose     = "StateRecoveryDemo"
}
</code></pre>
<p>This keeps environment-specific settings outside the main Terraform logic.</p>
<h2>Deploying the Infrastructure</h2>
<p>The infrastructure was deployed using the normal Terraform workflow:</p>
<pre><code class="language-bash">cd environments/dev
terraform init
terraform fmt
terraform validate
terraform plan
terraform apply
</code></pre>
<p>After applying, Terraform created the VPC, subnet, and security group in AWS.</p>
<p>Terraform also created a local state file:</p>
<pre><code class="language-text">terraform.tfstate
</code></pre>
<p>This state file contained the mapping between the Terraform code and real AWS resources.</p>
<p>To confirm what Terraform was tracking, I used:</p>
<pre><code class="language-bash">terraform state list
</code></pre>
<p>Expected output:</p>
<pre><code class="language-text">aws_security_group.web_sg
aws_subnet.public
aws_vpc.recovery_demo
</code></pre>
<p>This confirmed that Terraform knew about all three resources.</p>
<h2>Simulating Accidental State Deletion</h2>
<p>To simulate state loss, I first created a backup:</p>
<pre><code class="language-bash">cp terraform.tfstate terraform.tfstate.backup
</code></pre>
<p>Then I deleted the state file:</p>
<pre><code class="language-bash">rm terraform.tfstate
</code></pre>
<p>This simulates a real-world mistake where the Terraform state file is accidentally deleted.</p>
<p>At this point, the AWS resources still exist.</p>
<p>But Terraform no longer knows about them.</p>
<p>Running:</p>
<pre><code class="language-bash">terraform state list
</code></pre>
<p>would show that Terraform has no tracked resources.</p>
<p>This is the key lesson:</p>
<pre><code class="language-text">Deleting state does not delete AWS infrastructure.
It only deletes Terraform’s memory of that infrastructure.
</code></pre>
<h2>What Happens After State Loss?</h2>
<p>After deleting the state file, running:</p>
<pre><code class="language-bash">terraform plan
</code></pre>
<p>causes Terraform to behave as if the resources do not exist.</p>
<p>Terraform may try to create the VPC, subnet, and security group again.</p>
<p>This is dangerous because the real infrastructure already exists in AWS.</p>
<p>The correct solution is not to recreate everything.</p>
<p>The correct solution is to import the existing resources back into Terraform state.</p>
<h2>Finding Existing AWS Resource IDs</h2>
<p>Before importing, Terraform needs the real AWS IDs.</p>
<p>I used AWS CLI to find them.</p>
<p>Find the VPC ID:</p>
<pre><code class="language-bash">aws ec2 describe-vpcs \
  --filters "Name=tag:Name,Values=dev-state-recovery-vpc" \
  --query "Vpcs[0].VpcId" \
  --output text
</code></pre>
<p>Find the subnet ID:</p>
<pre><code class="language-bash">aws ec2 describe-subnets \
  --filters "Name=tag:Name,Values=dev-state-recovery-public-subnet" \
  --query "Subnets[0].SubnetId" \
  --output text
</code></pre>
<p>Find the security group ID:</p>
<pre><code class="language-bash">aws ec2 describe-security-groups \
  --filters "Name=group-name,Values=dev-state-recovery-web-sg" \
  --query "SecurityGroups[0].GroupId" \
  --output text
</code></pre>
<p>These commands return IDs like:</p>
<pre><code class="language-text">vpc-xxxxxxxx
subnet-xxxxxxxx
sg-xxxxxxxx
</code></pre>
<p>These IDs are required for import.</p>
<h2>Recovering State Using terraform import</h2>
<p>The <code>terraform import</code> command reconnects existing AWS resources with Terraform state.</p>
<p>Import the VPC:</p>
<pre><code class="language-bash">terraform import aws_vpc.recovery_demo vpc-xxxxxxxx
</code></pre>
<p>Import the subnet:</p>
<pre><code class="language-bash">terraform import aws_subnet.public subnet-xxxxxxxx
</code></pre>
<p>Import the security group:</p>
<pre><code class="language-bash">terraform import aws_security_group.web_sg sg-xxxxxxxx
</code></pre>
<p>This does not create new infrastructure.</p>
<p>It only updates Terraform state and tells Terraform:</p>
<pre><code class="language-text">This existing AWS resource belongs to this Terraform resource block.
</code></pre>
<p>For example:</p>
<pre><code class="language-bash">terraform import aws_vpc.recovery_demo vpc-xxxxxxxx
</code></pre>
<p>means:</p>
<pre><code class="language-text">The existing AWS VPC with this ID should now be tracked as aws_vpc.recovery_demo.
</code></pre>
<h2>Verifying Recovery</h2>
<p>After importing all resources, I checked state again:</p>
<pre><code class="language-bash">terraform state list
</code></pre>
<p>Expected output:</p>
<pre><code class="language-text">aws_security_group.web_sg
aws_subnet.public
aws_vpc.recovery_demo
</code></pre>
<p>Then I ran:</p>
<pre><code class="language-bash">terraform plan
</code></pre>
<p>The ideal result is:</p>
<pre><code class="language-text">No changes. Your infrastructure matches the configuration.
</code></pre>
<p>If Terraform still shows changes, that means the imported AWS resources do not fully match the Terraform code.</p>
<p>This can happen if some resource settings were created differently or changed manually.</p>
<h2>Drift Detection</h2>
<p>Drift happens when the real infrastructure is different from the Terraform code.</p>
<p>For example:</p>
<pre><code class="language-text">Terraform code says VPC Name tag = dev-state-recovery-vpc
AWS Console manually changes it to dev-state-recovery-vpc-manual-change
</code></pre>
<p>Now Terraform code and AWS are not aligned.</p>
<p>To detect drift, run:</p>
<pre><code class="language-bash">terraform plan
</code></pre>
<p>Terraform will compare:</p>
<pre><code class="language-text">Terraform code
Terraform state
Actual AWS infrastructure
</code></pre>
<p>If it finds differences, it shows what needs to change.</p>
<p>This is called drift detection.</p>
<h2>Handling Drift</h2>
<p>There are two ways to handle drift.</p>
<p>The first option is to keep Terraform as the source of truth.</p>
<p>If the manual AWS change was wrong, run:</p>
<pre><code class="language-bash">terraform apply
</code></pre>
<p>Terraform will revert AWS back to what the code says.</p>
<p>The second option is to accept the manual change.</p>
<p>If the manual change was correct, update the Terraform code to match the new desired state, then run:</p>
<pre><code class="language-bash">terraform plan
terraform apply
</code></pre>
<p>The important rule is simple:</p>
<pre><code class="language-text">Do not leave AWS and Terraform code different from each other.
</code></pre>
<p>Either fix AWS or update the code.</p>
<h2>Modern Best Practice: Remote Backend</h2>
<p>Using local state is risky.</p>
<p>For real projects, state should be stored remotely in S3 with locking.</p>
<p>A modern backend setup includes:</p>
<pre><code class="language-text">S3 bucket for remote state
Bucket versioning for recovery
Encryption for protection
DynamoDB locking to prevent simultaneous state changes
</code></pre>
<p>Example backend:</p>
<pre><code class="language-hcl">terraform {
  backend "s3" {
    bucket         = "asignment-4-terraform-state-34-238-244-58"
    key            = "dev/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "asignment-4-terraform-locks"
    encrypt        = true
  }
}
</code></pre>
<p>This improves safety because state is no longer stored only on one machine.</p>
<p>S3 versioning also helps recover previous versions if the state object is accidentally changed or deleted.</p>
<h2>Lessons Learned</h2>
<p>This assignment taught me that Terraform state is not just a background file. It is a critical part of infrastructure management.</p>
<p>The most important lessons were:</p>
<pre><code class="language-text">Terraform state is Terraform’s memory
Deleting state does not delete infrastructure
State loss can cause Terraform to recreate resources
terraform import can rebuild state tracking
terraform plan can detect drift
Remote state is safer than local state
Manual AWS Console changes should be avoided
</code></pre>
<h2>Why This Project Matters for DevOps</h2>
<p>This project is valuable because state recovery is a real operational skill.</p>
<p>In DevOps, Cloud Engineering, Platform Engineering, and SRE roles, engineers must know how to recover from mistakes safely.</p>
<p>Creating infrastructure is only one part of the job.</p>
<p>Managing state, detecting drift, recovering resources, and avoiding downtime are equally important.</p>
<p>This assignment demonstrates practical understanding of:</p>
<pre><code class="language-text">Terraform state management
Disaster recovery
AWS CLI usage
Resource import
Drift detection
Infrastructure troubleshooting
Remote backend best practices
</code></pre>
<h2>Conclusion</h2>
<p>Terraform makes infrastructure repeatable and manageable, but Terraform depends heavily on state.</p>
<p>If the state is lost, Terraform loses track of the infrastructure it manages. The infrastructure may still exist in AWS, but Terraform no longer knows how to control it.</p>
<p>By using <code>terraform import</code>, we can reconnect existing resources to Terraform state. By using <code>terraform plan</code>, we can detect drift. By using remote backend storage, versioning, and locking, we can reduce the risk of state loss in the first place.</p>
<p>This assignment shows an important real-world DevOps lesson:</p>
<pre><code class="language-text">Good infrastructure engineering is not only about building systems.
It is also about recovering them safely when something goes wrong.
</code></pre>
]]></content:encoded></item></channel></rss>