Skip to content
CloudOps
All prompts
AI for Terraform Difficulty: Intermediate ClaudeChatGPT

Terraform State Backend Design Prompt

Design Terraform state backend — S3+DynamoDB, GCS, Azure Blob, encryption, locking, versioning, cross-account access.

Target user
Platform engineers managing Terraform state at scale
Difficulty
Intermediate
Tools
Claude, ChatGPT

The prompt

You are a senior platform engineer who has set up Terraform state backends across cloud providers — secure, locked, versioned, with cross-team access patterns.

I will provide:
- The cloud provider
- Team / multi-env structure
- Current state setup (local or remote)
- Symptom (lost state, no locking, version drift)

Your job:

1. **Backend choice**:
   - **`s3` + DynamoDB** — AWS; encryption + locking standard
   - **`gcs`** — GCP; locking via object metadata
   - **`azurerm`** — Azure Blob; locking via lease
   - **Terraform Cloud / Enterprise** — managed; RBAC, runs, policy
   - **`http`** — GitLab managed; locking built-in
2. **For S3 backend essentials**:
   - **Versioning ON** — recover from accidental writes
   - **Encryption** (SSE-S3 or SSE-KMS)
   - **Block public access**
   - **DynamoDB table** for state locking (PK: `LockID`)
   - **Server-side replication** for DR
3. **For state path organization**:
   - Per-env: `env/prod/network/terraform.tfstate`
   - Per-team: `teams/payments/...`
   - One state file per logical boundary
   - **Smaller states = faster plans, lower blast radius**
4. **For workspaces**:
   - Suffix on state path
   - Limited; prefer directory structure for true env separation
5. **For cross-account**:
   - Assume role in backend config
   - Or read-only state across accounts
6. **For locking semantics**:
   - DynamoDB lock: TTL, force-unlock for stuck
   - GCS: similar via metadata
   - Lock during plan AND apply
7. **For IAM design**:
   - Minimum: S3 list/get/put on path; DynamoDB get/put/delete
   - State contains secrets — encryption key control matters
8. **For migration**:
   - `terraform init -migrate-state` to move
   - Backup before
   - Coordinate downtime

Mark DESTRUCTIVE: deleting state bucket (unrecoverable), DynamoDB table delete during apply, broad IAM on state.

---

Cloud: [AWS / GCP / Azure / TFC]
Team structure: [DESCRIBE]
Current setup: [DESCRIBE]
Symptom: [DESCRIBE]

Why this prompt works

State is Terraform’s most critical resource. This prompt walks setup.

How to use it

  1. Backend with locking from day 1.
  2. Versioning ON.
  3. Encryption at rest.
  4. One state per boundary.

Patterns

S3 + DynamoDB

terraform {
  backend "s3" {
    bucket         = "myorg-terraform-state-prod"
    key            = "network/vpc/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    kms_key_id     = "arn:aws:kms:us-east-1:123:key/abc"
    dynamodb_table = "terraform-state-locks"

    # Cross-account assume role
    role_arn = "arn:aws:iam::987654321:role/TerraformBackend"
  }
}

Backend setup (one-time, bootstrap)

# bootstrap/main.tf  (run once, manually)
resource "aws_s3_bucket" "state" {
  bucket = "myorg-terraform-state-prod"
}

resource "aws_s3_bucket_versioning" "state" {
  bucket = aws_s3_bucket.state.id
  versioning_configuration { status = "Enabled" }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "state" {
  bucket = aws_s3_bucket.state.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.state.arn
    }
  }
}

resource "aws_s3_bucket_public_access_block" "state" {
  bucket                  = aws_s3_bucket.state.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_dynamodb_table" "locks" {
  name         = "terraform-state-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
  server_side_encryption { enabled = true }
}

GCS backend

terraform {
  backend "gcs" {
    bucket = "myorg-tfstate"
    prefix = "env/prod/network"

    # Optional: encryption via CMEK
    encryption_key = "base64-encoded-key"
  }
}

State path strategy

myorg-terraform-state-prod/
├── network/
│   ├── vpc/terraform.tfstate
│   └── transit-gateway/terraform.tfstate
├── platform/
│   ├── eks-cluster/terraform.tfstate
│   └── rds-shared/terraform.tfstate
└── apps/
    ├── payments/terraform.tfstate
    └── web/terraform.tfstate

Smaller states = faster plans, lower blast radius.

Common findings this catches

  • No versioning → enable; backup history.
  • No locking → two concurrent applies corrupt state.
  • Plain text state → enable encryption.
  • Monolithic state → split by team / system.
  • Workspaces masquerading as envs → switch to dirs.
  • State exposed publicly → block public access.
  • Cross-account IAM too broad → scope.

When to escalate

  • State migration at scale — coordinated.
  • Multi-region DR — strategic.
  • Terraform Cloud adoption — eval.

Related prompts

Newsletter

Get weekly AI workflows for DevOps engineers

Practical prompts, automation ideas, and tool reviews for infrastructure engineers. One email per week. No spam.