interview-prep

Crisp answer: Use separate directories per environment, each with its own backend and variable values. Avoid workspaces for long-lived environments. Share infrastructure code via modules.

The directory-per-environment pattern:

infra/
├── modules/
│   ├── networking/    # VPC, subnets, SGs
│   ├── eks/           # EKS cluster, node groups
│   └── rds/           # Aurora cluster
├── environments/
│   ├── dev/
│   │   ├── main.tf
│   │   ├── backend.tf
│   │   └── terraform.tfvars
│   ├── staging/
│   │   ├── main.tf
│   │   ├── backend.tf
│   │   └── terraform.tfvars
│   └── prod/
│       ├── main.tf
│       ├── backend.tf
│       └── terraform.tfvars

Each environment's main.tf calls the same modules but passes different variable values:

# environments/prod/main.tf
module "eks" {
  source = "../../modules/eks"

  cluster_name   = "prod-cluster"
  instance_types = ["m5.xlarge"]
  min_size       = 3
  max_size       = 10
}

# environments/dev/main.tf
module "eks" {
  source = "../../modules/eks"

  cluster_name   = "dev-cluster"
  instance_types = ["t3.medium"]
  min_size       = 1
  max_size       = 3
}

Variable files per environment:

# environments/prod/terraform.tfvars
region         = "eu-west-2"
instance_type  = "m5.xlarge"
replica_count  = 3
enable_deletion_protection = true

# environments/dev/terraform.tfvars
region         = "eu-west-2"
instance_type  = "t3.small"
replica_count  = 1
enable_deletion_protection = false

Separate backends per environment:

# environments/prod/backend.tf
terraform {
  backend "s3" {
    bucket = "mycompany-terraform-state-prod"
    key    = "prod/terraform.tfstate"
    region = "eu-west-2"
  }
}

# environments/dev/backend.tf
terraform {
  backend "s3" {
    bucket = "mycompany-terraform-state-dev"
    key    = "dev/terraform.tfstate"
    region = "eu-west-2"
  }
}

Separate buckets per environment mean a compromise of the dev state file cannot affect production.

CI/CD per environment:

# On PR: plan dev
# On merge to main: apply dev
# After dev passes: plan staging
# Manual approval: apply staging
# Manual approval: apply prod

What to say in the interview:

"I use separate directories per environment rather than workspaces. Each environment directory has its own backend so state is completely isolated. The shared infrastructure logic lives in modules and each environment calls those modules with its own variable values — smaller instance types in dev, full HA config in prod. In CI the pipeline flows through environments in order with a manual approval gate before production. This makes it impossible to accidentally apply a production change to the wrong account."

My notes