Comprehensive templates and patterns for creating Terraform module examples. Use when creating examples/ directory, writing inline examples in README.md, or needing example file templates (main.tf, variables.tf, outputs.tf, versions.tf, README.md). Covers basic/complete/scenario examples, placeholder conventions, and testing workflows for ECS, load balancer, and secrets modules.
examples/ directory structureThis skill provides comprehensive reference for creating runnable Terraform module examples. Examples demonstrate real-world usage patterns and help users understand module implementation.
Minimal Setup - Required:
module "basic_service" {
source = "github.com/Luscii/terraform-aws-ecs-service"
# Required variables only
name = "my-service"
ecs_cluster_name = "production"
vpc_id = "vpc-12345678"
subnets = ["subnet-12345678", "subnet-87654321"]
task_cpu = 256
task_memory = 512
container_definitions = [{
name = "app"
image = "nginx:latest"
}]
task_role = { name = "task-role", arn = "arn:aws:iam::123456789012:role/task-role" }
execution_role = { name = "exec-role", arn = "arn:aws:iam::123456789012:role/exec-role" }
context = module.label.context
}
Characteristics:
Advanced Setup - Required:
module "label" {
source = "cloudposse/label/null"
version = "0.25.0"
namespace = "luscii"
environment = "production"
name = "api"
}
module "advanced_service" {
source = "github.com/Luscii/terraform-aws-ecs-service"
name = module.label.name
ecs_cluster_name = "production"
vpc_id = "vpc-12345678"
subnets = ["subnet-12345678", "subnet-87654321"]
task_cpu = 1024
task_memory = 2048
container_definitions = [{
name = "app"
image = "myregistry.io/api:v1.2.3"
port_mappings = [{
containerPort = 8080
protocol = "tcp"
name = "http"
}]
environment = [
{ name = "ENVIRONMENT", value = "production" },
{ name = "LOG_LEVEL", value = "info" }
]
secrets = module.secrets.container_definition
}]
load_balancers = [{
target_group_arn = aws_lb_target_group.api.arn
container_name = "app"
container_port = 8080
}]
scaling = {
min_capacity = 2
max_capacity = 10
}
scaling_target = {
cpu = {
predefined_metric_type = "ECSServiceAverageCPUUtilization"
target_value = 70
}
}
task_role = module.task_role.role
execution_role = module.execution_role.role
context = module.label.context
}
# Output usage demonstration
resource "aws_route53_record" "api" {
zone_id = data.aws_route53_zone.main.zone_id
name = "api.example.com"
type = "A"
alias {
name = module.load_balancer.dns_name
zone_id = module.load_balancer.zone_id
evaluate_target_health = true
}
}
Characteristics:
When to Create:
Directory Structure:
examples/
├── README.md # Navigation to all examples
├── basic/ # Minimal working example
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ ├── versions.tf
│ └── README.md
├── complete/ # Full-featured example
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ ├── versions.tf
│ └── README.md
└── {scenario}/ # Use-case specific
├── main.tf
├── variables.tf
├── outputs.tf
├── versions.tf
└── README.md
# Provider configuration
provider "aws" {
region = var.region
}
# CloudPosse label module
module "label" {
source = "cloudposse/label/null"
version = "0.25.0"
namespace = var.namespace
environment = var.environment
name = var.name
}
# Reference parent module with relative path
module "example" {
source = "../../"
# Configuration specific to this scenario
name = module.label.name
# ... other variables
context = module.label.context
}
# Supporting resources (data sources, IAM roles, etc.)
data "aws_vpc" "this" {
id = var.vpc_id
}
# Output usage demonstration
resource "aws_route53_record" "example" {
# ... configuration
}
Best Practices:
source = "../../" for parent modulevariable "namespace" {
type = string
description = "Namespace for resource naming"
default = "example"
}
variable "environment" {
type = string
description = "Environment name (dev, staging, prod)"
default = "dev"
}
variable "name" {
type = string
description = "Name of the resource"
default = "demo"
}
variable "region" {
type = string
description = "AWS region for resources"
default = "eu-west-1"
}
variable "vpc_id" {
type = string
description = "VPC ID where resources will be created"
default = null
}
variable "subnet_ids" {
type = list(string)
description = "List of subnet IDs for resource placement"
default = []
}
Best Practices:
output "id" {
value = module.example.id
description = "Unique identifier of the created resource"
}
output "arn" {
value = module.example.arn
description = "ARN of the created resource"
}
output "name" {
value = module.example.name
description = "Name of the created resource"
}
output "url" {
value = module.example.url
description = "URL to access the resource"
}
output "security_group_id" {
value = module.example.security_group_id
description = "Security group ID for network configuration"
}
Best Practices:
terraform {
required_version = ">= 1.3"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 6.0"
}
}
}
Best Practices:
# {Scenario Name}
## Purpose
Brief description of what this example demonstrates and when to use it.
## What This Example Deploys
- Resource type 1 (e.g., ECS Fargate service with 2 tasks)
- Resource type 2 (e.g., Application Load Balancer)
- Resource type 3 (e.g., Auto-scaling configuration)
- Integration point (e.g., CloudWatch log group)
## Prerequisites
- Existing VPC with subnets
- ECS cluster (if applicable)
- IAM roles (if applicable)
- Valid AWS credentials configured
## Usage
```bash
# Set required variables (if not using defaults)
export TF_VAR_vpc_id="vpc-12345678"
export TF_VAR_subnet_ids='["subnet-12345678","subnet-87654321"]'
# Initialize Terraform
terraform init
# Review the plan
terraform plan
# Apply the configuration
terraform apply
Key configuration points:
After deployment:
# Get output values
terraform output
# Test functionality (example)
curl http://$(terraform output -raw alb_dns_name)/
terraform destroy
### examples/README.md (Root)
```markdown
# Examples
This directory contains examples demonstrating various ways to use this module.
## Available Examples
### [Basic Example](./basic/)
Minimal configuration showing the essential inputs required to use this module.
**Use this when:** You want the simplest possible setup to get started.
**Demonstrates:**
- Required variables only
- Minimal working configuration
- Basic module usage
---
### [Complete Example](./complete/)
Full-featured configuration demonstrating all major features and optional parameters.
**Use this when:** You need a production-ready configuration with common features.
**Demonstrates:**
- All important optional features
- Integration with other AWS services
- Output usage
- Production best practices
---
### [{Scenario Name}](./{scenario}/)
Brief description of the scenario.
**Use this when:** Specific use case description.
**Demonstrates:**
- Key feature 1
- Key feature 2
- Integration pattern
---
## Running Examples
Each example is self-contained. To run an example:
```bash
cd {example-directory}
terraform init
terraform plan
terraform apply
Common prerequisites for all examples:
To remove resources created by an example:
cd {example-directory}
terraform destroy
## Common Scenario Directories
### ECS Service Module
- `basic/` - Minimal service configuration
- `complete/` - Production-ready with all features
- `with-load-balancer/` - Service behind ALB
- `service-connect-only/` - Internal service using Service Connect
- `scheduled-task/` - Scheduled ECS task
- `with-autoscaling/` - Auto-scaling enabled
### Load Balancer Module
- `basic/` - Simple load balancer
- `complete/` - Full-featured ALB
- `public-alb/` - Internet-facing
- `internal-alb/` - Internal only
- `with-waf/` - WAF integration
### Secrets Module
- `basic/` - Simple secrets
- `new-secrets/` - Creating new secrets
- `existing-secrets/` - Using existing secrets
- `mixed/` - Combination of new and existing
## Placeholder Conventions
### In Code Comments
```terraform
# Replace with your VPC ID
vpc_id = "vpc-12345678"
# Replace with your subnet IDs
subnets = ["subnet-12345678", "subnet-87654321"]
Use angle brackets for placeholders:
<VPC_ID> - "e.g., vpc-12345678"<SUBNET_ID> - "e.g., subnet-12345678"<REGION> - "e.g., eu-west-1"Provide example values and where to find them.
variable "vpc_id" {
type = string
description = "VPC ID where resources will be created. Find in VPC console or use data source."
default = null # Or sensible default
}
Before committing examples:
terraform init succeedsterraform validate passesterraform fmt appliedterraform plan completes without errorssource = "../../"# .github/workflows/validate-examples.yml