Skip to content

Terraform — Operations

Scope

State management, workspace patterns, CI/CD integration, drift detection, and operational best practices.

State Management

Backend Configuration

Backend State Locking Encryption Team Use Cost
S3 + DynamoDB Yes SSE-S3/KMS Multi-user Low
GCS Yes (native) Yes Multi-user Low
Azure Blob Yes (lease) Yes Multi-user Low
Terraform Cloud Yes Yes Enterprise Free-$$
Consul Yes Optional Self-hosted Free
Local No No Single user Free
# Production S3 backend
terraform {
  backend "s3" {
    bucket         = "company-terraform-state"
    key            = "prod/network/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    kms_key_id     = "alias/terraform-state"
    dynamodb_table = "terraform-lock"
  }
}

State Operations

# Import existing resource
terraform import aws_instance.web i-1234567890abcdef0

# Move resource in state
terraform state mv aws_instance.old aws_instance.new

# Remove from state without destroying
terraform state rm aws_instance.decommissioned

# List all resources
terraform state list

# Show specific resource
terraform state show aws_instance.web

Workspace Patterns

Environment Isolation

# Per-environment workspaces
terraform workspace new staging
terraform workspace new production
terraform workspace select production

# Use workspace in configs
locals {
  env = terraform.workspace
  instance_type = {
    staging    = "t3.small"
    production = "t3.xlarge"
  }
}

Workspace vs Directory

For significantly different environments, use separate directories with shared modules instead of workspaces. Workspaces share the same backend config and variable structure.

CI/CD Integration

GitHub Actions Pattern

- name: Terraform Plan
  run: |
    terraform init -backend-config=backend.hcl
    terraform plan -out=tfplan -input=false
    terraform show -json tfplan > plan.json

- name: Terraform Apply
  if: github.ref == 'refs/heads/main'
  run: terraform apply -auto-approve tfplan

Drift Detection

# Detect drift without applying
terraform plan -detailed-exitcode
# Exit code: 0 = no changes, 1 = error, 2 = changes detected

Performance Optimization

Strategy Impact When to Use
parallelism flag Faster apply Large infra (default: 10)
-refresh=false Skip state refresh When you know state is current
-target flag Apply specific resources Emergency fixes (avoid in CI)
Module splitting Reduce blast radius 50+ resources per state
Provider caching Faster init CI/CD pipelines

Common Issues

Issue Root Cause Resolution
State lock stuck Crashed apply terraform force-unlock <ID>
Provider version conflict Loose constraints Pin provider versions exactly
Cycle detected Circular dependencies Use depends_on or restructure
State drift Manual changes terraform refresh then fix
Slow plan Large state file Split into smaller states