mcpField
T
terraform-module-creator

terraform-module-creator

github.com/c0x12cCloud & DevOps109105 installsUpdated 19w ago
Repository

About terraform-module-creator

This skill creates or extends reusable Terraform infrastructure modules for teams managing cloud resources. It structures files, variables, and outputs according to stated conventions, and includes a usage example and consistency checks.

Key features

  1. 01Create or extend Terraform modules
  2. 02Organize files by resource type
  3. 03Define typed, validated input variables
  4. 04Add outputs, version constraints, and examples
  5. 05Check naming and interface consistency

Use cases

  1. 01Refactor inline resources into a reusable module
  2. 02Create a standard module for cloud resources
  3. 03Standardize an existing module's structure and interface

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/c0x12c/ai-toolkit --skill terraform-module-creator

After installing, type/terraform-module-creatorin Claude Code to confirm it loaded.

Details

From the project README

Terraform Module Creator

Creates or extends reusable Terraform modules following standard conventions for structure, interfaces, and composition.

When to Use

  • Creating a new reusable infrastructure module
  • Extending an existing module with new resources
  • Refactoring inline resources into a proper module
  • Standardizing an ad-hoc module to follow conventions

Process

1. Determine Module Purpose

Ask the user:

  • Module name (e.g., rds, ecs-service, s3-bucket)
  • Resources managed (what AWS/cloud resources it wraps)
  • Consumers (which services will use this module)
2. Create Module Directory
modules/{module-name}/
  main.tf           # Core resource or locals
  variables.tf      # All input variables
  outputs.tf        # All outputs
  {resource}.tf     # One file per resource type
  versions.tf       # Provider version constraints
  README.md         # Auto-generated usage docs
3. Define Variables
# variables.tf — explicit interfaces, no hardcoded defaults for critical values

variable "name" {
  description = "Resource name prefix"
  type        = string

  validation {
    condition     = can(regex("^[a-z][a-z0-9-]+$", var.name))
    error_message = "Name must be lowercase alphanumeric with hyphens."
  }
}

variable "vpc_id" {
  description = "VPC ID where resources are deployed"
  type        = string
}

variable "subnet_ids" {
  description = "Subnet IDs for resource placement"
  type        = list(string)
}

variable "tags" {
  description = "Additional tags to apply to all resources"
  type        = map(string)
  default     = {}
}

# Use object types for grouped config
variable "backup" {
  description = "Backup configuration"
  type = object({
    enabled          = bool
    retention_days   = number
    window           = optional(string, "03:00-04:00")
  })
  default = {
    enabled        = true
    retention_days = 7
  }
}
4. Resource Per File
# rds.tf — one resource type per file
resource "aws_db_instance" "this" {
  identifier     = var.name
  engine         = var.engine
  engine_version = var.engine_version
  instance_class = var.instance_class

  allocated_storage     = var.allocated_storage
  max_allocated_storage = var.max_allocated_storage

  db_name  = var.db_name
  username = var.master_username
  password = var.master_password

  db_subnet_group_name   = aws_db_subnet_group.this.name
  vpc_security_group_ids = [aws_security_group.rds.id]

  backup_retention_period = var.backup.retention_days
  backup_window           = var.backup.window
  deletion_protection     = var.deletion_protection

  tags = merge(var.tags, {
    Name = var.name
  })
}

resource "aws_db_subnet_group" "this" {
  name       = "${var.name}-subnet-group"
  subnet_ids = var.subnet_ids

  tags = merge(var.tags, {
    Name = "${var.name}-subnet-group"
  })
}
5. Security Group Per Resource
# sg.tf
resource "aws_security_group" "rds" {
  name_prefix = "${var.name}-rds-"
  vpc_id      = var.vpc_id
  description = "Security group for ${var.name} RDS instance"

  tags = merge(var.tags, {
    Name = "${var.name}-rds-sg"
  })

  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_security_group_rule" "rds_ingress" {
  type                     = "ingress"
  from_port                = 5432
  to_port                  = 5432
  protocol                 = "tcp"
  security_group_id        = aws_security_group.rds.id
  source_security_group_id = var.app_security_group_id
  description              = "Allow access from application"
}
6. Define Outputs
# outputs.tf — expose values that consumers need
output "endpoint" {
  description = "Database connection endpoint"
  value       = aws_db_instance.this.endpoint
}

output "port" {
  description = "Database port"
  value       = aws_db_instance.this.port
}

output "security_group_id" {
  description = "Security group ID for the database"
  value       = aws_security_group.rds.id
}

output "arn" {
  description = "ARN of the database instance"
  value       = aws_db_instance.this.arn
}

# Mark sensitive outputs
output "connection_string" {
  description = "Full connection string"
  value       = "postgresql://${var.master_username}:${var.master_password}@${aws_db_instance.this.endpoint}/${var.db_name}"
  sensitive   = true
}
7. Version Constraints
# versions.tf
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0"
    }
  }
}
8. Publishing to Registry

New modules should be contributed to the c0x12c Terraform Registry:

  1. Create a new repo at https://github.com/c0x12c/terraform-aws-{module-name} following the Terraform registry naming convention
  2. Push the module code with proper versions.tf, variables.tf, outputs.tf
  3. Tag a release: git tag v0.1.0 && git push --tags
  4. The registry auto-publishes from GitHub tags
  5. Consumers then use: source = "c0x12c/{module-name}/aws" with version = "~> 0.1.0"
9. Module Usage Example
# How consumers call this module — use c0x12c registry
module "database" {
  source  = "c0x12c/rds/aws"
  version = "~> 0.6.6"

  name            = "${local.name_prefix}-db"
  engine          = "postgres"
  engine_version  = "15.4"
  instance_class  = "db.t3.micro"
  allocated_storage = 20
  db_name         = "myservice"
  master_username = "admin"
  master_password = var.db_password
  vpc_id          = local.vpc_id
  subnet_ids      = local.private_subnet_ids
  app_security_group_id = module.ecs_service.security_group_id

  deletion_protection = var.env == "prod"

  backup = {
    enabled        = true
    retention_days = var.env == "prod" ? 30 : 7
  }

  tags = local.common_tags
}

Interaction Style

  • Asks module purpose and consumers before generating
  • Creates complete module in one pass
  • Includes usage example showing how to call the module
  • Validates naming and interface consistency

Rules

  • NO provider blocks in modules — providers come from the caller
  • NO hardcoded values — everything via variables
  • Explicit interfaces — every input has description, type, and validation where useful
  • One resource per file — named after the resource type
  • Use this as the resource name for the primary resource
  • name_prefix over name for security groups (allows create-before-destroy)
  • Mark sensitive outputs with sensitive = true
  • Use object() types for grouped configuration
  • Use optional() for fields with sensible defaults
  • Version constraints in versions.tf, not main.tf
  • Tags passed through and merged, never overridden
  • Lifecycle rules for zero-downtime updates where applicable

Output

Produces a module directory:

modules/{module-name}/
  main.tf
  variables.tf
  outputs.tf
  versions.tf
  sg.tf
  {resource-1}.tf
  {resource-2}.tf

Plus a usage snippet for consumers to copy.

Comments

Markdown supported