Terraform Best Practices
Expert guidance for building production-grade Terraform infrastructure with enterprise patterns for module design, state management, security, testing, and multi-environment deployments.
When to Use This Skill
- Writing reusable Terraform modules for teams or organizations
- Setting up secure remote state management and backend configuration
- Designing multi-environment infrastructure (dev/staging/prod)
- Implementing infrastructure CI/CD pipelines with automated validation
- Managing infrastructure at scale across multiple teams or projects
- Migrating from manual infrastructure to infrastructure-as-code
- Refactoring existing Terraform for better maintainability
- Implementing security best practices for infrastructure code
Core Concepts
Module Design Philosophy
- Composition over monoliths: Break infrastructure into reusable child modules
- Standard structure: main.tf, variables.tf, outputs.tf, versions.tf, README.md
- Type constraints: Use validation blocks and complex types for safety
- Dynamic blocks: Enable flexible configuration without duplication
State Management Principles
- Remote backends: S3+DynamoDB or Terraform Cloud for team collaboration
- State encryption: KMS encryption at rest and in transit (mandatory)
- State locking: Prevent concurrent modifications with DynamoDB
- Workspace strategy: Directory-based for production, workspaces for similar envs
Security Fundamentals
- Secret management: AWS Secrets Manager, HashiCorp Vault (never hardcode)
- Least privilege: Separate IAM roles per environment
- Security scanning: tfsec, Checkov, Terrascan in CI/CD
- Resource tagging: Enable cost tracking, ownership, compliance
Testing & Validation
- Pre-commit hooks: Format, validate, lint before commits
- Plan review: Always save and review plans before apply
- Automated testing: Terratest for critical infrastructure modules
- Policy as code: OPA/Sentinel for compliance enforcement
Quick Reference
| Task |
Load reference |
| Module structure, variables, outputs, dynamic blocks |
skills/terraform-best-practices/references/module-design.md |
| Remote backends, state encryption, workspace strategies |
skills/terraform-best-practices/references/state-management.md |
| Variable precedence, tfvars, Terragrunt DRY config |
skills/terraform-best-practices/references/environment-management.md |
| Secrets, IAM, scanning tools, resource tagging |
skills/terraform-best-practices/references/security.md |
| Pre-commit hooks, Terratest, policy as code |
skills/terraform-best-practices/references/testing-validation.md |
| Comprehensive checklist for all areas |
skills/terraform-best-practices/references/best-practices-summary.md |
Workflow
1. Project Setup
# Initialize directory structure
mkdir -p {modules,environments/{dev,staging,prod}}
# Set up remote backend (bootstrap S3 + DynamoDB first)
# Configure backend.tf with encryption and locking
2. Module Development
# Create module with standard structure
cd modules/my-module
touch main.tf variables.tf outputs.tf versions.tf README.md
# Add validation to variables
# Use complex types for structured inputs
# Document outputs with descriptions
3. Security Hardening
# Mark sensitive variables
# Use secret management for credentials
# Configure state encryption
# Set up security scanning in CI/CD
4. Testing Pipeline
# Install pre-commit hooks
pre-commit install
# Run validation locally
terraform init
terraform validate
terraform fmt -check
# Security scanning
tfsec .
checkov -d .
# Automated tests (critical modules)
cd tests && go test -v
5. Deployment Process
# Plan with output file
terraform plan -out=tfplan
# Review plan thoroughly
terraform show tfplan
# Apply only after approval
terraform apply tfplan
# Verify deployment
terraform output
6. Multi-Environment Management
# Use directory-based isolation for production
cd environments/prod
terraform init
terraform workspace list
# Or use Terragrunt for DRY backend config
terragrunt plan
Common Mistakes
❌ Hardcoding secrets in code → Use secret management services
❌ No state locking → Enable DynamoDB locking to prevent conflicts
❌ Skipping plan review → Always save and review execution plans
❌ No version constraints → Pin provider and module versions
❌ Local state in teams → Use remote backends for collaboration
❌ No security scanning → Integrate tfsec/Checkov in CI/CD
❌ Missing resource tags → Tag all resources for cost/ownership tracking
❌ No automated testing → Write Terratest for critical modules
❌ Monolithic modules → Break into composable child modules
❌ No backup strategy → Enable S3 versioning on state buckets
Resources
1---2name: terraform-best-practices3description: Terraform infrastructure-as-code best practices for scalable and maintainable cloud infrastructure. Use when writing Terraform modules, managing infrastructure state, or implementing infrastructure automation at scale.4---5
6# Terraform Best Practices
7
8Expert guidance for building production-grade Terraform infrastructure with enterprise patterns for module design, state management, security, testing, and multi-environment deployments.
9
10## When to Use This Skill
11
12- Writing reusable Terraform modules for teams or organizations
13- Setting up secure remote state management and backend configuration
14- Designing multi-environment infrastructure (dev/staging/prod)
15- Implementing infrastructure CI/CD pipelines with automated validation
16- Managing infrastructure at scale across multiple teams or projects
17- Migrating from manual infrastructure to infrastructure-as-code
18- Refactoring existing Terraform for better maintainability
19- Implementing security best practices for infrastructure code
20
21## Core Concepts
22
23### Module Design Philosophy
24- **Composition over monoliths**: Break infrastructure into reusable child modules
25- **Standard structure**: main.tf, variables.tf, outputs.tf, versions.tf, README.md
26- **Type constraints**: Use validation blocks and complex types for safety
27- **Dynamic blocks**: Enable flexible configuration without duplication
28
29### State Management Principles
30- **Remote backends**: S3+DynamoDB or Terraform Cloud for team collaboration
31- **State encryption**: KMS encryption at rest and in transit (mandatory)
32- **State locking**: Prevent concurrent modifications with DynamoDB
33- **Workspace strategy**: Directory-based for production, workspaces for similar envs
34
35### Security Fundamentals
36- **Secret management**: AWS Secrets Manager, HashiCorp Vault (never hardcode)
37- **Least privilege**: Separate IAM roles per environment
38- **Security scanning**: tfsec, Checkov, Terrascan in CI/CD
39- **Resource tagging**: Enable cost tracking, ownership, compliance
40
41### Testing & Validation
42- **Pre-commit hooks**: Format, validate, lint before commits
43- **Plan review**: Always save and review plans before apply
44- **Automated testing**: Terratest for critical infrastructure modules
45- **Policy as code**: OPA/Sentinel for compliance enforcement
46
47## Quick Reference
48
49| Task | Load reference |
50| --- | --- |
51| Module structure, variables, outputs, dynamic blocks | `skills/terraform-best-practices/references/module-design.md` |
52| Remote backends, state encryption, workspace strategies | `skills/terraform-best-practices/references/state-management.md` |
53| Variable precedence, tfvars, Terragrunt DRY config | `skills/terraform-best-practices/references/environment-management.md` |
54| Secrets, IAM, scanning tools, resource tagging | `skills/terraform-best-practices/references/security.md` |
55| Pre-commit hooks, Terratest, policy as code | `skills/terraform-best-practices/references/testing-validation.md` |
56| Comprehensive checklist for all areas | `skills/terraform-best-practices/references/best-practices-summary.md` |
57
58## Workflow
59
60### 1. Project Setup
61```bash
62# Initialize directory structure
63mkdir -p {modules,environments/{dev,staging,prod}}
64
65# Set up remote backend (bootstrap S3 + DynamoDB first)
66# Configure backend.tf with encryption and locking
67```
68
69### 2. Module Development
70```bash
71# Create module with standard structure
72cd modules/my-module
73touch main.tf variables.tf outputs.tf versions.tf README.md
74
75# Add validation to variables
76# Use complex types for structured inputs
77# Document outputs with descriptions
78```
79
80### 3. Security Hardening
81```bash
82# Mark sensitive variables
83# Use secret management for credentials
84# Configure state encryption
85# Set up security scanning in CI/CD
86```
87
88### 4. Testing Pipeline
89```bash
90# Install pre-commit hooks
91pre-commit install
92
93# Run validation locally
94terraform init
95terraform validate
96terraform fmt -check
97
98# Security scanning
99tfsec .
100checkov -d .
101
102# Automated tests (critical modules)
103cd tests && go test -v
104```
105
106### 5. Deployment Process
107```bash
108# Plan with output file
109terraform plan -out=tfplan
110
111# Review plan thoroughly
112terraform show tfplan
113
114# Apply only after approval
115terraform apply tfplan
116
117# Verify deployment
118terraform output
119```
120
121### 6. Multi-Environment Management
122```bash
123# Use directory-based isolation for production
124cd environments/prod
125terraform init
126terraform workspace list
127
128# Or use Terragrunt for DRY backend config
129terragrunt plan
130```
131
132## Common Mistakes
133
134❌ **Hardcoding secrets in code** → Use secret management services
135❌ **No state locking** → Enable DynamoDB locking to prevent conflicts
136❌ **Skipping plan review** → Always save and review execution plans
137❌ **No version constraints** → Pin provider and module versions
138❌ **Local state in teams** → Use remote backends for collaboration
139❌ **No security scanning** → Integrate tfsec/Checkov in CI/CD
140❌ **Missing resource tags** → Tag all resources for cost/ownership tracking
141❌ **No automated testing** → Write Terratest for critical modules
142❌ **Monolithic modules** → Break into composable child modules
143❌ **No backup strategy** → Enable S3 versioning on state buckets
144
145## Resources
146
147- **Official Docs**: https://developer.hashicorp.com/terraform/docs
148- **Style Guide**: https://developer.hashicorp.com/terraform/language/syntax/style
149- **Module Registry**: https://registry.terraform.io/
150- **Terragrunt**: https://terragrunt.gruntwork.io/
151- **Terratest**: https://terratest.gruntwork.io/
152- **tfsec**: https://aquasecurity.github.io/tfsec/
153- **Checkov**: https://www.checkov.io/
154- **Best Practices**: https://www.terraform-best-practices.com/
155- **AWS Provider**: https://registry.terraform.io/providers/hashicorp/aws/latest/docs