mcpField
T
terraform-module-creator

terraform-module-creator

github.com/c0x12cクラウド・DevOps109105 回インストール19 週間前に更新
リポジトリ

terraform-module-creator について

クラウドリソースを管理するチーム向けに、再利用可能な Terraform インフラストラクチャモジュールを作成・拡張するスキルです。定められた規約に沿ってファイル、変数、出力を構成し、使用例と整合性チェックも用意します。

主な機能

  1. 01Terraformモジュールの作成・拡張
  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 Registry の命名規約に従い、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
}

対話スタイル

  • 生成前に、モジュールの目的と利用者を確認します
  • モジュール一式を一度に作成します
  • モジュールの呼び出し方を示す使用例を含めます
  • 命名とインターフェースの一貫性を検証します

ルール

  • モジュール内にプロバイダーブロックを記述しません。プロバイダーは呼び出し元から渡されます
  • ハードコードされた値を使用しません。すべて変数で指定します
  • 明示的なインターフェースにします。すべての入力に説明と型を指定し、必要に応じて検証も設定します
  • リソースごとにファイルを作成し、リソースタイプにちなんだ名前を付けます
  • プライマリリソース名には this を使用します
  • セキュリティグループでは name より name_prefix を優先します(先に作成してから置き換えられるようにするため)
  • 機密性の高い出力には sensitive = true を設定します
  • グループ化された設定には object() 型を使用します
  • 適切なデフォルト値があるフィールドには optional() を使用します
  • バージョン制約は main.tf ではなく versions.tf に記述します
  • タグは受け渡してマージし、上書きしません
  • 適用可能な場合は、ダウンタイムなしで更新するためのライフサイクルルールを設定します

出力

次のモジュールディレクトリを生成します。

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

さらに、利用者がコピーして使えるコードスニペットも提供します。

コメント