Terraform IaC Standards
Overview
This skill ensures consistent Terraform configurations across the team by enforcing naming conventions, security requirements, and module structure standards.
Module Structure
code
modules/
├── vpc/
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── versions.tf
├── eks/
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── versions.tf
└── rds/
├── main.tf
├── variables.tf
├── outputs.tf
└── versions.tf
Naming Conventions
- •Resources:
{env}-{project}-{resource-type}- •Example:
prod-webapp-vpc,dev-api-rds
- •Example:
- •Variables:
snake_case- •Example:
instance_type,vpc_cidr
- •Example:
- •Outputs:
{resource}_id,{resource}_arn- •Example:
vpc_id,cluster_arn
- •Example:
- •Local variables:
snake_casewithlocal.prefix - •Data sources:
{provider}_{type}_{purpose}
Required Tags
All resources must include these tags:
hcl
tags = {
Environment = var.environment
Project = var.project_name
ManagedBy = "terraform"
Owner = var.team_email
CostCenter = var.cost_center
CreatedAt = timestamp()
}
Security Requirements
Secrets Management
- •NEVER hardcode secrets in .tf files
- •Use AWS Secrets Manager or HashiCorp Vault
- •Reference secrets via data sources:
hcl
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "prod/database/password"
}
Encryption
- •Enable encryption at rest for all storage (S3, EBS, RDS)
- •Enable encryption in transit (TLS/SSL)
- •Use KMS customer-managed keys for sensitive workloads
Network Security
- •Restrict security groups to minimum required ports
- •Use private subnets for databases and backend services
- •Enable VPC flow logs for audit trails
- •Never use 0.0.0.0/0 for ingress except load balancers on 443
File Organization
main.tf
hcl
# Provider configuration
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "terraform-state-bucket"
key = "env/project/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
# Resources
resource "aws_vpc" "main" {
# ...
}
variables.tf
hcl
variable "environment" {
description = "Deployment environment (dev, staging, prod)"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
outputs.tf
hcl
output "vpc_id" {
description = "The ID of the VPC"
value = aws_vpc.main.id
}
Validation Commands
Run before every apply:
bash
# Format check terraform fmt -check -recursive # Validate syntax terraform validate # Security scan tfsec . # Cost estimation infracost breakdown --path . # Plan review terraform plan -out=tfplan
State Management
- •Use remote state (S3 + DynamoDB for locking)
- •Never commit .tfstate files
- •Use workspaces for environment separation
- •Enable state file encryption
Common Patterns
Multi-Environment Setup
hcl
locals {
env_config = {
dev = {
instance_type = "t3.small"
min_capacity = 1
}
prod = {
instance_type = "t3.large"
min_capacity = 3
}
}
config = local.env_config[var.environment]
}
Conditional Resource Creation
hcl
resource "aws_cloudwatch_log_group" "app" {
count = var.enable_logging ? 1 : 0
name = "/app/${var.project_name}"
}