brainupgrade-in avatar

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
  • Variables: snake_case
    • Example: instance_type, vpc_cidr
  • Outputs: {resource}_id, {resource}_arn
    • Example: vpc_id, cluster_arn
  • Local variables: snake_case with local. 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}"
}
terraform-iac - AI Agent Skill for Claude Code & Cursor | Agent Skills