
terraform-iac
Creates and validates Terraform configurations following company standards. Use when writing or revi
by brainupgrade-in|Open Source
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
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:
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:
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
# 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
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
output "vpc_id" {
description = "The ID of the VPC"
value = aws_vpc.main.id
}
Validation Commands
Run before every apply:
# 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
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
resource "aws_cloudwatch_log_group" "app" {
count = var.enable_logging ? 1 : 0
name = "/app/${var.project_name}"
}