mcpField
T
terraform-module-creator

terraform-module-creator

github.com/c0x12c云与 DevOps109105 次安装19 周前更新
代码仓库

关于 terraform-module-creator

此技能用于创建或扩展可复用的 Terraform 基础设施模块,面向管理云资源的团队。它按约定组织文件、变量和输出,并提供模块调用示例及一致性检查。

主要功能

  1. 01创建或扩展 Terraform 模块
  2. 02按资源类型组织模块文件
  3. 03定义带类型和验证的输入变量
  4. 04生成输出、版本约束和用法示例
  5. 05检查命名与接口一致性

适用场景

  1. 01将内联资源重构为可复用模块
  2. 02为新云资源创建标准模块
  3. 03规范现有模块的目录和接口

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/terraform-module-creator确认已加载。

详细介绍

Terraform 模块创建器

按照标准的结构、接口和组合约定,创建或扩展可复用的 Terraform 模块。

适用场景

  • 创建新的可复用基础设施模块
  • 为现有模块添加新资源
  • 将内联资源重构为合适的模块
  • 将临时模块规范化,使其符合约定

流程

1. 确定模块用途

询问用户:

  • 模块名称(例如,rds、ecs-service、s3-bucket)
  • 管理的资源(模块封装了哪些 AWS/云资源)
  • 使用方(哪些服务将使用此模块)
2. 创建模块目录
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. 定义变量
# 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. 每个资源单独一个文件
# 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. 每个资源对应一个安全组
# 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. 定义输出
# 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. 版本约束
# versions.tf
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0"
    }
  }
}
8. 发布到注册表

新模块应贡献到 c0x12c Terraform Registry:

  1. 按照 Terraform 注册表的命名约定,在 https://github.com/c0x12c/terraform-aws-{module-name} 创建新仓库
  2. 推送模块代码,并确保包含正确的 versions.tf、variables.tf、outputs.tf
  3. 为发布版本打标签:git tag v0.1.0 && git push --tags
  4. 注册表会根据 GitHub 标签自动发布
  5. 使用方随后可通过 source = "c0x12c/{module-name}/aws" 和 version = "~> 0.1.0" 使用该模块
9. 模块使用示例
# 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
}

交互方式

  • 生成前询问模块用途和使用方
  • 一次性创建完整模块
  • 附上展示如何调用模块的使用示例
  • 验证命名和接口的一致性

规则

  • 模块中不得包含 provider 块——provider 由调用方提供
  • 不得硬编码值——所有值均通过变量传递
  • 接口应明确——每个输入都应有描述、类型,并在适用时添加验证
  • 每个资源单独一个文件——文件以资源类型命名
  • 主资源的资源名称使用 this
  • 安全组优先使用 name_prefix 而非 name(支持先创建后销毁)
  • 敏感输出标记为 sensitive = true
  • 对成组的配置使用 object() 类型
  • 对有合理默认值的字段使用 optional()
  • 在 versions.tf 中而非 main.tf 中声明版本约束
  • 标签应传递并合并,不得覆盖
  • 在适用时使用生命周期规则,实现零停机更新

输出

生成一个模块目录:

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

并附上供使用方复制的用法片段。

评论

支持 Markdown