By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
For engineers who need to deploy, debug, and secure Terraform in production—fast.
The terraform.tfstate file is Terraform’s single source of truth for your infrastructure. It maps your Terraform config (.tf files) to real-world resources (e.g., AWS EC2 instances, S3 buckets). Without it, Terraform doesn’t know what it’s managing—like a GPS without a map.
terraform.tfstate
.tf
If two engineers run terraform apply at the same time, they can corrupt the state file, leading to: - Drift: Terraform thinks a resource exists when it doesn’t (or vice versa). - Race conditions: Two applies overwrite each other’s changes. - Downtime: Accidental deletions or misconfigurations.
terraform apply
You’re on a team deploying a new microservice. Your coworker runs terraform apply while you’re mid-debug. Suddenly, your changes are overwritten, the load balancer disappears, and your CTO is asking why the site is down.
This guide will teach you: ? How to securely store and share the state file (no more local-only chaos). ? How to prevent concurrent changes with locking. ? How to debug and recover from state corruption. ? How to automate state management in CI/CD.
terraform state
json { "version": 4, "terraform_version": "1.5.0", "resources": [ { "type": "aws_instance", "name": "web_server", "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", "instances": [{ "attributes": { "id": "i-1234567890abcdef0" } }] } ] }
hcl terraform { backend "s3" { bucket = "my-terraform-state-bucket" key = "prod/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-lock-table" # For locking } }
Error: Error acquiring the state lock
terraform state list
terraform state show aws_instance.web
terraform state rm aws_instance.old_server
terraform state mv aws_instance.old aws_instance.new
bash terraform plan -detailed-exitcode
2
terraform refresh
bash terraform refresh
>= 1.0.0
aws configure
aws s3api create-bucket \ --bucket my-terraform-state-bucket \ --region us-east-1 \ --create-bucket-configuration LocationConstraint=us-east-1
Enable versioning (for rollbacks):
aws s3api put-bucket-versioning \ --bucket my-terraform-state-bucket \ --versioning-configuration Status=Enabled
Enable encryption (SSE-S3):
aws s3api put-bucket-encryption \ --bucket my-terraform-state-bucket \ --server-side-encryption-configuration '{ "Rules": [{ "ApplyServerSideEncryptionByDefault": { "SSEAlgorithm": "AES256" } }] }'
aws dynamodb create-table \ --table-name terraform-lock-table \ --attribute-definitions AttributeName=LockID,AttributeType=S \ --key-schema AttributeName=LockID,KeyType=HASH \ --billing-mode PAY_PER_REQUEST
Create backend.tf:
backend.tf
terraform { backend "s3" { bucket = "my-terraform-state-bucket" key = "prod/terraform.tfstate" region = "us-east-1" dynamodb_table = "terraform-lock-table" encrypt = true } }
terraform init
Expected output:
Successfully configured the backend "s3"! Terraform will automatically use this backend unless the backend configuration changes.
bash terraform apply
Error: Error acquiring the state lock Lock Info: ID: 123e4567-e89b-12d3-a456-426614174000 Path: my-terraform-state-bucket/prod/terraform.tfstate Operation: OperationTypeApply Who: user@host Version: 1.5.0 Created: 2023-10-01 12:00:00 +0000 UTC Info:
If a lock is orphaned (e.g., a crashed terraform apply), manually unlock:
terraform force-unlock LOCK_ID
Example:
terraform force-unlock 123e4567-e89b-12d3-a456-426614174000
hcl data "aws_iam_policy_document" "terraform_state" { statement { actions = ["s3:ListBucket"] resources = ["arn:aws:s3:::my-terraform-state-bucket"] } statement { actions = ["s3:GetObject", "s3:PutObject"] resources = ["arn:aws:s3:::my-terraform-state-bucket/*"] } statement { actions = ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:DeleteItem"] resources = ["arn:aws:dynamodb:us-east-1:123456789012:table/terraform-lock-table"] } }
sensitive = true
terraform output -json
bash aws s3api put-bucket-lifecycle-configuration \ --bucket my-terraform-state-bucket \ --lifecycle-configuration '{ "Rules": [{ "ID": "MoveOldVersionsToGlacier", "Status": "Enabled", "Filter": {}, "Transitions": [{ "Days": 30, "StorageClass": "GLACIER" }] }] }'
prod/
staging/
hcl resource "aws_instance" "web" { tags = { Environment = "prod" Terraform = "true" } }
terraform_remote_state
hcl data "terraform_remote_state" "network" { backend = "s3" config = { bucket = "my-terraform-state-bucket" key = "network/terraform.tfstate" region = "us-east-1" } }
terraform plan
sensitive
terraform.tfstate*
.gitignore
"How do you migrate from local to remote state?"-terraform init -migrate-state.
terraform init -migrate-state
State management:
terraform state rm aws_instance.web
"How do you detect drift?"-terraform plan -detailed-exitcode (exit code 2).
terraform plan -detailed-exitcode
Locking:
refresh
plan
"Your team uses S3 for remote state. After a terraform apply, the state file is corrupted. How do you recover?" Answer:1. Restore the last good version from S3 versioning.2. Run terraform refresh to sync with real-world infra.3. If needed, manually edit the state file (last resort).
You have a legacy Terraform config using local state. Migrate it to S3 + DynamoDB locking without downtime.
bash terraform init -migrate-state
bash aws s3 ls s3://my-terraform-state-bucket/prod/
Why it works: - -migrate-state copies local state to S3 without destroying resources. - DynamoDB ensures no concurrent changes during migration.
-migrate-state
grep
terraform state list \| grep aws_instance
terraform state show RESOURCE
terraform state rm RESOURCE
terraform state mv OLD NEW
LOCK_ID
backend "s3" { ... }
dynamodb_table
backend "remote" { ... }
encrypt = true
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.