✊ State File (terraform.tfstate)

→ Terraform’s memory
→ Stores unique ID for each resource, attributes
👉 State = Terraform’s source of truth. (Never Delete)

Must be:

  • Protected
  • Not edited manually
  • Stored remotely (S3 + DynamoDB lock recommended)

⭐ State File Lifecycle

Every Terraform command uses the state file:

  • terraform init
    → initializes backend
    → downloads providers
    → prepares state handling (no lock)

  • terraform plan
    → reads current tfstate
    → reads real infra (AWS)
    → shows diff only (no change, no lock)

  • terraform apply
    → acquires state lock (.terraform.tfstate.lock.info) → reads current state
    → updates real infra
    → writes updated state
    → releases lock

  • terraform destroy
    → acquires state lock
    → deletes real infra
    → updates state
    → releases lock

  • terraform refresh (implicit)
    → syncs state with real infra
    → no changes applied

⭐ Useful Terraform State Commands

Syntax:

terraform state <subcommand> [options] [args]
CommandUse
terraform state listShows all managed resources
terraform state show <resourceType.resourceName>Shows details of a resource from state
terraform state pullDownloads and prints remote state
terraform state rm <resourceType.resourceName>Removes resource from state (unmanaged)
terraform state mv <resourceType.resourceName1> <resourceType.resourceName2>Renames or moves a resource in state

☁️ Remote Backend – TF State


⭐ Remote Backend (S3)

Remote backend stores state in AWS S3 instead of local.

Benefits:

  • ✔ Secure, centralized storage
  • ✔ Versioning & backups
  • ✔ Team collaboration
  • ✔ Locking Prevents two people running Terraform at the same time.

Backend block: Backend bucket must always exist before Terraform runs.

terraform {
  backend "s3" {
    bucket         = "my-tf-state"
    key            = "dev/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    use_lockfile   = true
  }
}

⭐ Remote State File Structure (S3)

Example S3 folder:

my-tf-state/
  dev/terraform.tfstate
  test/terraform.tfstate
  prod/terraform.tfstate

Use separate state for:
✔ dev
✔ test
✔ prod