terraform-patterns

Best practices for Terraform infrastructure as code.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "terraform-patterns" with this command: npx skills add mindmorass/reflex/mindmorass-reflex-terraform-patterns

Terraform Patterns

Best practices for Terraform infrastructure as code.

Project Structure

infrastructure/ ├── modules/ │ ├── networking/ │ │ ├── main.tf │ │ ├── variables.tf │ │ ├── outputs.tf │ │ └── README.md │ ├── compute/ │ └── database/ ├── environments/ │ ├── dev/ │ │ ├── main.tf │ │ ├── terraform.tfvars │ │ └── backend.tf │ ├── staging/ │ └── prod/ ├── global/ │ ├── iam/ │ └── dns/ └── scripts/ └── init-backend.sh

Module Design

Reusable Module Pattern

modules/vpc/variables.tf

variable "name" { description = "Name prefix for resources" type = string }

variable "environment" { description = "Environment name" type = string validation { condition = contains(["dev", "staging", "prod"], var.environment) error_message = "Environment must be dev, staging, or prod." } }

variable "cidr_block" { description = "VPC CIDR block" type = string default = "10.0.0.0/16" validation { condition = can(cidrhost(var.cidr_block, 0)) error_message = "Must be a valid CIDR block." } }

variable "availability_zones" { description = "List of availability zones" type = list(string) }

variable "tags" { description = "Additional tags" type = map(string) default = {} }

modules/vpc/main.tf

locals { common_tags = merge(var.tags, { Module = "vpc" Environment = var.environment ManagedBy = "terraform" }) }

resource "aws_vpc" "main" { cidr_block = var.cidr_block enable_dns_hostnames = true enable_dns_support = true

tags = merge(local.common_tags, { Name = "${var.name}-vpc" }) }

resource "aws_subnet" "public" { count = length(var.availability_zones) vpc_id = aws_vpc.main.id cidr_block = cidrsubnet(var.cidr_block, 8, count.index) availability_zone = var.availability_zones[count.index]

map_public_ip_on_launch = true

tags = merge(local.common_tags, { Name = "${var.name}-public-${count.index + 1}" Tier = "public" }) }

resource "aws_subnet" "private" { count = length(var.availability_zones) vpc_id = aws_vpc.main.id cidr_block = cidrsubnet(var.cidr_block, 8, count.index + 10) availability_zone = var.availability_zones[count.index]

tags = merge(local.common_tags, { Name = "${var.name}-private-${count.index + 1}" Tier = "private" }) }

modules/vpc/outputs.tf

output "vpc_id" { description = "VPC ID" value = aws_vpc.main.id }

output "public_subnet_ids" { description = "List of public subnet IDs" value = aws_subnet.public[*].id }

output "private_subnet_ids" { description = "List of private subnet IDs" value = aws_subnet.private[*].id }

output "vpc_cidr_block" { description = "VPC CIDR block" value = aws_vpc.main.cidr_block }

State Management

Remote Backend Configuration

backend.tf

terraform { backend "s3" { bucket = "company-terraform-state" key = "environments/prod/terraform.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "terraform-locks"

# Assume role for cross-account access
role_arn = "arn:aws:iam::ACCOUNT_ID:role/TerraformStateAccess"

} }

State Locking Table

global/state-backend/main.tf

resource "aws_s3_bucket" "terraform_state" { bucket = "company-terraform-state"

lifecycle { prevent_destroy = true } }

resource "aws_s3_bucket_versioning" "terraform_state" { bucket = aws_s3_bucket.terraform_state.id versioning_configuration { status = "Enabled" } }

resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state" { bucket = aws_s3_bucket.terraform_state.id rule { apply_server_side_encryption_by_default { sse_algorithm = "aws:kms" } } }

resource "aws_dynamodb_table" "terraform_locks" { name = "terraform-locks" billing_mode = "PAY_PER_REQUEST" hash_key = "LockID"

attribute { name = "LockID" type = "S" } }

Provider Configuration

Multi-Region Setup

provider "aws" { region = var.primary_region

default_tags { tags = { Environment = var.environment Project = var.project_name ManagedBy = "terraform" } } }

provider "aws" { alias = "dr" region = var.dr_region

default_tags { tags = { Environment = var.environment Project = var.project_name ManagedBy = "terraform" } } }

Version Constraints

terraform { required_version = ">= 1.5.0"

required_providers { aws = { source = "hashicorp/aws" version = "> 5.0" } kubernetes = { source = "hashicorp/kubernetes" version = "> 2.23" } } }

Data Sources and Lookups

Look up existing resources

data "aws_vpc" "selected" { filter { name = "tag:Environment" values = [var.environment] } }

data "aws_ami" "amazon_linux" { most_recent = true owners = ["amazon"]

filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } }

data "aws_caller_identity" "current" {} data "aws_region" "current" {}

Conditional Resources

Create resource only in production

resource "aws_cloudwatch_metric_alarm" "high_cpu" { count = var.environment == "prod" ? 1 : 0

alarm_name = "${var.name}-high-cpu" comparison_operator = "GreaterThanThreshold" evaluation_periods = 2 metric_name = "CPUUtilization" namespace = "AWS/EC2" period = 300 statistic = "Average" threshold = 80 }

Dynamic blocks for optional configurations

resource "aws_security_group" "main" { name = "${var.name}-sg" vpc_id = var.vpc_id

dynamic "ingress" { for_each = var.ingress_rules content { from_port = ingress.value.from_port to_port = ingress.value.to_port protocol = ingress.value.protocol cidr_blocks = ingress.value.cidr_blocks } } }

Lifecycle Rules

resource "aws_instance" "web" { ami = data.aws_ami.amazon_linux.id instance_type = var.instance_type

lifecycle { create_before_destroy = true prevent_destroy = var.environment == "prod"

ignore_changes = [
  tags["LastModified"],
  user_data,
]

} }

Testing with Terratest

// test/vpc_test.go package test

import ( "testing" "github.com/gruntwork-io/terratest/modules/terraform" "github.com/stretchr/testify/assert" )

func TestVpcModule(t *testing.T) { terraformOptions := &terraform.Options{ TerraformDir: "../modules/vpc", Vars: map[string]interface{}{ "name": "test", "environment": "dev", "cidr_block": "10.0.0.0/16", "availability_zones": []string{"us-east-1a", "us-east-1b"}, }, }

defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)

vpcId := terraform.Output(t, terraformOptions, "vpc_id")
assert.NotEmpty(t, vpcId)

}

CI/CD Integration

.github/workflows/terraform.yml

name: Terraform

on: pull_request: paths: - 'infrastructure/' push: branches: [main] paths: - 'infrastructure/'

jobs: plan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Setup Terraform
    uses: hashicorp/setup-terraform@v3
    with:
      terraform_version: 1.5.0

  - name: Terraform Init
    run: terraform init
    working-directory: infrastructure/environments/${{ github.event.inputs.environment }}

  - name: Terraform Plan
    run: terraform plan -out=tfplan
    working-directory: infrastructure/environments/${{ github.event.inputs.environment }}

  - name: Upload Plan
    uses: actions/upload-artifact@v4
    with:
      name: tfplan
      path: infrastructure/environments/${{ github.event.inputs.environment }}/tfplan

References

  • Terraform Documentation

  • Terraform Best Practices

  • AWS Provider Documentation

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

github-harvester

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

microsoft-code-reference

No summary provided by upstream source.

Repository SourceNeeds Review
General

ffmpeg-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

site-crawler

No summary provided by upstream source.

Repository SourceNeeds Review