250 lines
5.6 KiB
Markdown
250 lines
5.6 KiB
Markdown
---
|
|
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
|