.github/skills/tsh-implementing-terraform-modules/SKILL.md
Build reusable Terraform modules for AWS, Azure, and GCP infrastructure following infrastructure-as-code best practices. Use when creating infrastructure modules, standardizing cloud provisioning, or implementing reusable IaC components.
npx skillsauth add thesoftwarehouse/copilot-collections tsh-implementing-terraform-modulesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Production-ready Terraform module patterns for AWS, Azure, and GCP infrastructure.
Create reusable, well-tested Terraform modules for common cloud infrastructure patterns across multiple cloud providers.
terraform-modules/
├── aws/
│ ├── vpc/
│ ├── eks/
│ ├── rds/
│ └── s3/
├── azure/
│ ├── vnet/
│ ├── aks/
│ └── storage/
└── gcp/
├── vpc/
├── gke/
└── cloud-sql/
module-name/
├── main.tf # Main resources
├── variables.tf # Input variables
├── outputs.tf # Output values
├── versions.tf # Provider versions
├── README.md # Documentation
├── examples/ # Usage examples
│ └── complete/
│ ├── main.tf
│ └── variables.tf
└── tests/ # Terratest files
└── module_test.go
main.tf:
resource "aws_vpc" "main" {
cidr_block = var.cidr_block
enable_dns_hostnames = var.enable_dns_hostnames
enable_dns_support = var.enable_dns_support
tags = merge(
{
Name = var.name
},
var.tags
)
}
resource "aws_subnet" "private" {
count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
tags = merge(
{
Name = "${var.name}-private-${count.index + 1}"
Tier = "private"
},
var.tags
)
}
resource "aws_internet_gateway" "main" {
count = var.create_internet_gateway ? 1 : 0
vpc_id = aws_vpc.main.id
tags = merge(
{
Name = "${var.name}-igw"
},
var.tags
)
}
variables.tf:
variable "name" {
description = "Name of the VPC"
type = string
}
variable "cidr_block" {
description = "CIDR block for VPC"
type = string
validation {
condition = can(cidrnetmask(var.cidr_block))
error_message = "CIDR block must be valid IPv4 CIDR notation."
}
}
variable "availability_zones" {
description = "List of availability zones"
type = list(string)
}
variable "private_subnet_cidrs" {
description = "CIDR blocks for private subnets"
type = list(string)
default = []
}
variable "enable_dns_hostnames" {
description = "Enable DNS hostnames in VPC"
type = bool
default = true
}
variable "enable_dns_support" {
description = "Enable DNS support in VPC"
type = bool
default = true
}
variable "create_internet_gateway" {
description = "Whether to create an Internet Gateway"
type = bool
default = true
}
variable "tags" {
description = "Additional tags"
type = map(string)
default = {}
}
outputs.tf:
output "vpc_id" {
description = "ID of the VPC"
value = aws_vpc.main.id
}
output "private_subnet_ids" {
description = "IDs of private subnets"
value = aws_subnet.private[*].id
}
output "vpc_cidr_block" {
description = "CIDR block of VPC"
value = aws_vpc.main.cidr_block
}
aws ~> 6.0, azurerm ~> 4.0, google ~> 5.0references/aws-modules.md - AWS module patternsreferences/azure-modules.md - Azure module patternsreferences/gcp-modules.md - GCP module patternsUse Terratest (Go) to test Terraform modules. Every module must include:
examples/complete/ — a root module that calls the module under test with realistic values and re-exports its outputstests/module_test.go — Go test file that runs InitAndApply, reads outputs, asserts expected values, and always defers DestroyApply the following rules when writing tests:
t.Parallel()terraform.WithDefaultRetryableErrorsruntime.Caller(0) to resolve examples/complete/ path relative to the test file — never use hardcoded relative pathssingle_nat_gateway = true (or equivalent cost-reducing flags) in test examplesInitAndPlanAndShowWithStruct) for fast PR validation that requires no AWS credentials-timeout 30m in CI to avoid hanging runsUse plain Terraform when:
Use Terragrunt when:
run-all, dependency orchestration)Terragrunt Golden Path structure:
infrastructure/
├── terragrunt.hcl # Root config (remote_state, generate provider)
├── _envcommon/ # Shared module references
│ ├── vpc.hcl
│ ├── eks.hcl
│ └── rds.hcl
├── dev/
│ ├── env.hcl # Environment-level vars
│ ├── vpc/terragrunt.hcl
│ └── eks/terragrunt.hcl
├── staging/
│ └── ...
└── prod/
└── ...
tsh-designing-multi-cloud-architecture - For architectural decisionstsh-optimizing-cloud-cost - For cost-effective designsdevelopment
Custom hook and composable patterns — naming, composition, stable return shapes, lifecycle cleanup, and testing strategies. Use when writing reusable logic units (React hooks, Vue composables), refactoring logic into hooks, debugging hook behavior, or reviewing hook implementations.
testing
UI verification criteria, structure checklists, severity definitions, and tolerance rules for comparing implementations against Figma designs. Use for verifying UI matches design, understanding what to check, and determining acceptable differences.
development
Clean raw workshop or meeting transcripts from small talk, filler words, and off-topic tangents. Extract and structure business-relevant content into a standardized format with discussion topics, key decisions, action items, and open questions.
development
Discover and establish technical context before implementing any feature. Prioritize project instructions, existing codebase patterns, and external documentation in that order. Use for any task requiring understanding of project conventions, coding standards, architecture patterns, and established practices before writing code.