Enterprise-grade Terraform best practices for building secure, scalable, and maintainable infrastructure.
- Required MCP Server:
hashicorp/terraform-mcp-serverfor comprehensive Terraform provider access - Terraform >= 1.5.0
- AWS Provider ~> 5.0
Follow consistent naming standards:
- Use underscores (never dashes)
- Include environment prefixes:
prod_,dev_,staging_ - Be descriptive about purpose
- Never include secrets in names
# Example
resource "aws_instance" "prod_web_server" {
# Configuration
}Standard project layout:
terraform-project/
├── main.tf # Main resources
├── variables.tf # Variable definitions
├── outputs.tf # Output values
├── providers.tf # Provider configuration
├── terraform.tfvars # Values (gitignored)
├── versions.tf # Version constraints
├── README.md # Documentation
├── environments/ # Per-environment configs
└── modules/ # Reusable components
Create modules when you have:
- Resources used across environments
- Complex configurations (3+ interconnected resources)
- Standardized security patterns
Never store state locally in production:
- Always use remote backend (S3 + DynamoDB)
- Always encrypt state
- Always enable state locking
- Separate state files per environment
terraform {
backend "s3" {
bucket = "company-terraform-state"
key = "environments/prod/terraform.tfstate"
region = "us-west-2"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}- NEVER hardcode credentials
- ALWAYS use IAM roles over access keys
- ALWAYS implement least privilege
- ALWAYS encrypt data at rest and in transit
- ALWAYS use current provider versions
Required tags for every resource:
- Environment
- Project
- ManagedBy (always "terraform")
- Owner
- CostCenter
- CreatedDate
Validate all inputs:
variable "environment" {
description = "Environment name"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}- Never use
0.0.0.0/0for ingress unless absolutely necessary - Always add descriptions
- Use security group references over CIDR blocks
- Implement least privilege access
# Initialize and validate
terraform init
terraform validate
terraform fmt -recursive
# Plan and apply
terraform plan -var-file="environments/dev/terraform.tfvars"
terraform apply -var-file="environments/dev/terraform.tfvars"
# State operations
terraform state list
terraform state show <resource>
# Cleanup
terraform destroy -var-file="environments/dev/terraform.tfvars"- All resources follow naming conventions
- Directory structure is organized
- Remote state backend configured
- Sensitive data is secured
- Input validation implemented
- Output values defined
- Security groups follow least privilege
- All resources tagged properly
- Version constraints specified
- Code formatted (
terraform fmt) - Configuration validated (
terraform validate) - Plan reviewed (
terraform plan)
- Always use feature branches
- Require pull request reviews
- Run
terraform planin CI - Format and validate before commit
- Never commit
.tfvarswith secrets - Use
.gitignorefor sensitive files
These guidelines are compiled from official best practices established by industry leaders:
- Collaborative Infrastructure as Code workflows using Terraform as core workflow
- Four stages of operational maturity for enterprise adoption
- Consistent code style with
terraform fmtandterraform validate - Workspace management with minimal blast radius
- Policy enforcement through HCP Terraform governance
- Infrastructure code quality and consistency across Terraform projects
- Accelerated developer onboarding and contribution capabilities
- Increased business agility through faster infrastructure changes
- Reduced errors and downtime in infrastructure deployments
- Optimized infrastructure costs and strengthened security posture
- Consistent, descriptive naming conventions for improved debugging and collaboration
- Standardized directory layouts for clarity, scalability, and efficiency
- Reusable modules that bundle common configurations for streamlined management
- Remote state storage, locking, backups, and access controls to prevent disasters
- Robust version control practices enabling rollbacks and audit trails
- CI/CD pipeline integration for automated validation, testing, and deployment
- Proactive security and governance measures with early vulnerability detection
Following these practices delivers:
- Secure infrastructure by default
- Scalable and maintainable deployments
- Consistent environments across dev/staging/prod
- Well-documented and team-accessible code
- Faster development cycles with reduced risk
Compiled from HashiCorp Developer Documentation, AWS Prescriptive Guidance, Firefly IaC Best Practices Guide, and enterprise Infrastructure as Code standards