Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Create reusable Terraform modules with proper input/output variables, remote state, and infrastructure best practices.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: terraform-module-library3description: Build reusable Terraform modules for AWS, Azure, GCP, and OCI infrastructure following infrastructure-as-code best practices. Use when creating infrastructure modules, standardizing cloud provisioning, or implementing reusable IaC components.4---56# Terraform Module Library78Production-ready Terraform module patterns for AWS, Azure, GCP, and OCI infrastructure.910## Purpose1112Create reusable, well-tested Terraform modules for common cloud infrastructure patterns across multiple cloud providers.1314## When to Use1516- Build reusable infrastructure components17- Standardize cloud resource provisioning18- Implement infrastructure as code best practices19- Create multi-cloud compatible modules20- Establish organizational Terraform standards2122## Module Structure2324```25terraform-modules/26├── aws/27│ ├── vpc/28│ ├── eks/29│ ├── rds/30│ └── s3/31├── azure/32│ ├── vnet/33│ ├── aks/34│ └── storage/35├── gcp/36│ ├── vpc/37│ ├── gke/38│ └── cloud-sql/39└── oci/40├── vcn/41├── oke/42└── object-storage/43```4445## Standard Module Pattern4647```48module-name/49├── main.tf # Main resources50├── variables.tf # Input variables51├── outputs.tf # Output values52├── versions.tf # Provider versions53├── README.md # Documentation54├── examples/ # Usage examples55│ └── complete/56│ ├── main.tf57│ └── variables.tf58└── tests/ # Terratest files59└── module_test.go60```6162## AWS VPC Module Example6364**main.tf:**6566```hcl67resource "aws_vpc" "main" {68cidr_block = var.cidr_block69enable_dns_hostnames = var.enable_dns_hostnames70enable_dns_support = var.enable_dns_support7172tags = merge(73{74Name = var.name75},76var.tags77)78}7980resource "aws_subnet" "private" {81count = length(var.private_subnet_cidrs)82vpc_id = aws_vpc.main.id83cidr_block = var.private_subnet_cidrs[count.index]84availability_zone = var.availability_zones[count.index]8586tags = merge(87{88Name = "${var.name}-private-${count.index + 1}"89Tier = "private"90},91var.tags92)93}9495resource "aws_internet_gateway" "main" {96count = var.create_internet_gateway ? 1 : 097vpc_id = aws_vpc.main.id9899tags = merge(100{101Name = "${var.name}-igw"102},103var.tags104)105}106```107108**variables.tf:**109110```hcl111variable "name" {112description = "Name of the VPC"113type = string114}115116variable "cidr_block" {117description = "CIDR block for VPC"118type = string119validation {120condition = can(regex("^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$", var.cidr_block))121error_message = "CIDR block must be valid IPv4 CIDR notation."122}123}124125variable "availability_zones" {126description = "List of availability zones"127type = list(string)128}129130variable "private_subnet_cidrs" {131description = "CIDR blocks for private subnets"132type = list(string)133default = []134}135136variable "enable_dns_hostnames" {137description = "Enable DNS hostnames in VPC"138type = bool139default = true140}141142variable "tags" {143description = "Additional tags"144type = map(string)145default = {}146}147```148149**outputs.tf:**150151```hcl152output "vpc_id" {153description = "ID of the VPC"154value = aws_vpc.main.id155}156157output "private_subnet_ids" {158description = "IDs of private subnets"159value = aws_subnet.private[*].id160}161162output "vpc_cidr_block" {163description = "CIDR block of VPC"164value = aws_vpc.main.cidr_block165}166```167168## Best Practices1691701. **Use semantic versioning** for modules1712. **Document all variables** with descriptions1723. **Provide examples** in examples/ directory1734. **Use validation blocks** for input validation1745. **Output important attributes** for module composition1756. **Pin provider versions** in versions.tf1767. **Use locals** for computed values1778. **Implement conditional resources** with count/for_each1789. **Test modules** with Terratest17910. **Tag all resources** consistently180181**Reference:** See `references/aws-modules.md` and `references/oci-modules.md`182183## Module Composition184185```hcl186module "vpc" {187source = "../../modules/aws/vpc"188189name = "production"190cidr_block = "10.0.0.0/16"191availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]192193private_subnet_cidrs = [194"10.0.1.0/24",195"10.0.2.0/24",196"10.0.3.0/24"197]198199tags = {200Environment = "production"201ManagedBy = "terraform"202}203}204205module "rds" {206source = "../../modules/aws/rds"207208identifier = "production-db"209engine = "postgres"210engine_version = "15.3"211instance_class = "db.t3.large"212213vpc_id = module.vpc.vpc_id214subnet_ids = module.vpc.private_subnet_ids215216tags = {217Environment = "production"218}219}220```221222223## Testing224225```go226// tests/vpc_test.go227package test228229import (230"testing"231"github.com/gruntwork-io/terratest/modules/terraform"232"github.com/stretchr/testify/assert"233)234235func TestVPCModule(t *testing.T) {236terraformOptions := &terraform.Options{237TerraformDir: "../examples/complete",238}239240defer terraform.Destroy(t, terraformOptions)241terraform.InitAndApply(t, terraformOptions)242243vpcID := terraform.Output(t, terraformOptions, "vpc_id")244assert.NotEmpty(t, vpcID)245}246```247248## Related Skills249250- `multi-cloud-architecture` - For architectural decisions251- `cost-optimization` - For cost-effective designs252