Initial commit
This commit is contained in:
249
skills/terraform-module-library/SKILL.md
Normal file
249
skills/terraform-module-library/SKILL.md
Normal file
@@ -0,0 +1,249 @@
|
||||
---
|
||||
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
|
||||
Reference in New Issue
Block a user