Terraform/OpenTofu Best Practices
Module Composition
- Organize code into reusable modules:
modules/{resource-type}/withmain.tf,variables.tf,outputs.tf - Use the
moduleblock to compose infrastructure: pass inputs via variables, expose outputs for downstream use - Follow the principle of one module per logical resource group (e.g.,
vpc,database,eks-cluster) - Version modules with git tags or registry versions:
source = "git::https://...?ref=v1.2.0" - Use
localsfor computed values and transformations; avoid complex logic inside resource blocks
State Management
- Store state remotely: use S3+DynamoDB (AWS), Azure Blob (Azure), or GCS (GCP) with locking enabled
- Never commit
.tfstateto version control -- it contains sensitive outputs - Use
state encryptionfor sensitive deployments; configure in the backend block - Run
terraform planbefore every apply; review the diff carefully for destructive changes - Use
terraform importto bring existing resources under Terraform management without recreation
Workspace Strategies
- Use Terraform workspaces for environment separation (dev/staging/prod) with identical configurations
- Map workspace names to environment-specific variables via
terraform.workspacein locals - For large-scale separation, prefer separate state files per environment over workspaces
- Label resources with workspace tags:
Environment = terraform.workspacefor cost tracking
Provider Configuration
- Pin provider versions with
required_providersblock:version = "~> 4.0" - Use
provideraliases for multi-region or multi-account deployments - Pass provider credentials via environment variables or IAM roles -- never hardcode in
.tffiles - Use
dynamicblocks for repeatable nested configurations: security group rules, IAM policies
Testing and Validation
- Run
terraform validateandterraform fmtin CI before every merge - Use
tflintfor linting beyond built-in validation: detect unused variables, deprecated syntax - Write Terratest integration tests for critical infrastructure:
terraform.InitAndApply+ assertions - Use
checkblocks (Terraform 1.3+) for custom data assertions without external tools - Implement
terraform planas a PR check; post the plan diff as a comment for review
Source: calcosmic/Aether — distributed by TomeVault.