home / skills / derklinke / codex-config / terraform-module-library

terraform-module-library skill

/skills/terraform-module-library

This skill helps you design reusable multi-cloud Terraform modules with standardized structures, promoting IaC best practices across AWS, Azure, and GCP.

npx playbooks add skill derklinke/codex-config --skill terraform-module-library

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
5.6 KB
---
name: terraform-module-library
description: 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.
---

# Terraform Module Library

Production-ready Terraform module patterns for AWS, Azure, and GCP infrastructure.

## Purpose

Create reusable, well-tested Terraform modules for common cloud infrastructure patterns across multiple cloud providers.

## When to Use

- Build reusable infrastructure components
- Standardize cloud resource provisioning
- Implement infrastructure as code best practices
- Create multi-cloud compatible modules
- Establish organizational Terraform standards

## Module Structure

```
terraform-modules/
├── aws/
│   ├── vpc/
│   ├── eks/
│   ├── rds/
│   └── s3/
├── azure/
│   ├── vnet/
│   ├── aks/
│   └── storage/
└── gcp/
    ├── vpc/
    ├── gke/
    └── cloud-sql/
```

## Standard Module Pattern

```
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
```

## AWS VPC Module Example

**main.tf:**

```hcl
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:**

```hcl
variable "name" {
  description = "Name of the VPC"
  type        = string
}

variable "cidr_block" {
  description = "CIDR block for VPC"
  type        = string
  validation {
    condition     = can(regex("^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$", 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 "tags" {
  description = "Additional tags"
  type        = map(string)
  default     = {}
}
```

**outputs.tf:**

```hcl
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
}
```

## Best Practices

1. **Use semantic versioning** for modules
2. **Document all variables** with descriptions
3. **Provide examples** in examples/ directory
4. **Use validation blocks** for input validation
5. **Output important attributes** for module composition
6. **Pin provider versions** in versions.tf
7. **Use locals** for computed values
8. **Implement conditional resources** with count/for_each
9. **Test modules** with Terratest
10. **Tag all resources** consistently

## Module Composition

```hcl
module "vpc" {
  source = "../../modules/aws/vpc"

  name               = "production"
  cidr_block         = "10.0.0.0/16"
  availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]

  private_subnet_cidrs = [
    "10.0.1.0/24",
    "10.0.2.0/24",
    "10.0.3.0/24"
  ]

  tags = {
    Environment = "production"
    ManagedBy   = "terraform"
  }
}

module "rds" {
  source = "../../modules/aws/rds"

  identifier     = "production-db"
  engine         = "postgres"
  engine_version = "15.3"
  instance_class = "db.t3.large"

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnet_ids

  tags = {
    Environment = "production"
  }
}
```

## Reference Files

- `assets/vpc-module/` - Complete VPC module example
- `assets/rds-module/` - RDS module example
- `references/aws-modules.md` - AWS module patterns
- `references/azure-modules.md` - Azure module patterns
- `references/gcp-modules.md` - GCP module patterns

## Testing

```go
// tests/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: "../examples/complete",
    }

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

    vpcID := terraform.Output(t, terraformOptions, "vpc_id")
    assert.NotEmpty(t, vpcID)
}
```

## Related Skills

- `multi-cloud-architecture` - For architectural decisions
- `cost-optimization` - For cost-effective designs

Overview

This skill provides a library of production-ready Terraform module patterns for AWS, Azure, and GCP, enabling teams to build reusable, well-structured infrastructure-as-code components. It focuses on consistent module layout, provider pinning, validation, testing, and cross-cloud compatibility to standardize provisioning across projects.

How this skill works

The skill supplies standardized module templates (main.tf, variables.tf, outputs.tf, versions.tf, examples, and tests) and concrete examples such as VPC, EKS/AKS/GKE, RDS/Cloud SQL, and storage modules. It enforces best practices like semantic versioning, input validation, documented variables, resource tagging, and Terratest-driven tests to validate modules before reuse. Modules are composed by referencing module outputs for downstream resources, supporting conditional resources and locals for computed values.

When to use it

  • Creating reusable infrastructure components for multiple projects or teams
  • Standardizing cloud provisioning across AWS, Azure, and GCP
  • Implementing IaC best practices (validation, versioning, testing)
  • Building multi-cloud compatible modules or platform catalogs
  • Onboarding teams to a consistent Terraform module pattern

Best practices

  • Follow the standard module pattern: main.tf, variables.tf, outputs.tf, versions.tf, examples/, tests/
  • Document every input variable and provide usage examples in examples/complete
  • Pin provider versions and use semantic versioning for module releases
  • Use validation blocks, locals, and conditional resources (count/for_each) for safe defaults
  • Expose essential outputs for module composition and tag all resources consistently
  • Write Terratest or equivalent integration tests and include cleanup (terraform destroy)

Example use cases

  • Create an AWS VPC module with private subnets, IGW, and tagged resources for production networks
  • Build an RDS/Cloud SQL module that consumes VPC outputs and returns database endpoints and IDs
  • Provide AKS/EKS/GKE cluster modules with configurable node pools and example deployments
  • Assemble a multi-cloud baseline with common networking and storage modules for platform teams
  • Publish a module catalog for CI/CD pipelines to pull pinned module versions

FAQ

How do I validate input CIDR blocks and other formats?

Use Terraform validation blocks with regex and can() to validate CIDR and other string patterns in variables.tf.

How should modules be tested before publishing?

Include examples/complete and Terratest (or similar) tests that init/apply the example, assert outputs, and run terraform destroy in teardown.