terraform-module-writer

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Terraform Module Writer

Terraform 模块编写指南

Эксперт по созданию высококачественных, переиспользуемых Terraform модулей с соблюдением industry best practices.
本指南用于创建符合行业最佳实践的高质量、可重用Terraform模块。

Module Structure

模块结构

Standard Directory Layout

标准目录布局

modules/
└── my-module/
    ├── main.tf           # Primary resource definitions
    ├── variables.tf      # Input variable declarations
    ├── outputs.tf        # Output value definitions
    ├── versions.tf       # Provider version constraints
    ├── locals.tf         # Local values and computations
    ├── data.tf           # Data source definitions
    ├── README.md         # Module documentation
    ├── CHANGELOG.md      # Version history
    ├── examples/
    │   ├── basic/
    │   │   ├── main.tf
    │   │   └── outputs.tf
    │   └── advanced/
    │       ├── main.tf
    │       └── outputs.tf
    └── tests/
        └── module_test.go
modules/
└── my-module/
    ├── main.tf           # 核心资源定义
    ├── variables.tf      # 输入变量声明
    ├── outputs.tf        # 输出值定义
    ├── versions.tf       # 提供商版本约束
    ├── locals.tf         # 本地值与计算逻辑
    ├── data.tf           # 数据源定义
    ├── README.md         # 模块文档
    ├── CHANGELOG.md      # 版本历史
    ├── examples/
    │   ├── basic/
    │   │   ├── main.tf
    │   │   └── outputs.tf
    │   └── advanced/
    │       ├── main.tf
    │       └── outputs.tf
    └── tests/
        └── module_test.go

versions.tf Template

versions.tf 模板

hcl
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0.0, < 6.0.0"
    }
    random = {
      source  = "hashicorp/random"
      version = ">= 3.5.0"
    }
  }
}

hcl
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0.0, < 6.0.0"
    }
    random = {
      source  = "hashicorp/random"
      version = ">= 3.5.0"
    }
  }
}

Input Variable Design

输入变量设计

Variable Declaration Best Practices

变量声明最佳实践

hcl
undefined
hcl
undefined

variables.tf

variables.tf

Required variables (no default)

必填变量(无默认值)

variable "name" { description = "Name prefix for all resources created by this module" type = string
validation { condition = can(regex("^[a-z][a-z0-9-]*$", var.name)) error_message = "Name must start with a letter and contain only lowercase letters, numbers, and hyphens." } }
variable "environment" { description = "Environment name (e.g., dev, staging, prod)" type = string
validation { condition = contains(["dev", "staging", "prod"], var.environment) error_message = "Environment must be one of: dev, staging, prod." } }
variable "name" { description = "本模块创建的所有资源的名称前缀" type = string
validation { condition = can(regex("^[a-z][a-z0-9-]*$", var.name)) error_message = "名称必须以字母开头,且仅包含小写字母、数字和连字符。" } }
variable "environment" { description = "环境名称(例如:dev、staging、prod)" type = string
validation { condition = contains(["dev", "staging", "prod"], var.environment) error_message = "环境必须是以下值之一:dev、staging、prod。" } }

Optional variables with sensible defaults

可选变量(含合理默认值)

variable "instance_type" { description = "EC2 instance type for the application servers" type = string default = "t3.medium"
validation { condition = can(regex("^[a-z][0-9][.][a-z]+$", var.instance_type)) error_message = "Instance type must be a valid AWS instance type format." } }
variable "enable_monitoring" { description = "Enable detailed monitoring for resources" type = bool default = true }
variable "min_instances" { description = "Minimum number of instances in the Auto Scaling Group" type = number default = 2
validation { condition = var.min_instances >= 1 && var.min_instances <= 100 error_message = "Minimum instances must be between 1 and 100." } }
variable "max_instances" { description = "Maximum number of instances in the Auto Scaling Group" type = number default = 10
validation { condition = var.max_instances >= 1 && var.max_instances <= 100 error_message = "Maximum instances must be between 1 and 100." } }
undefined
variable "instance_type" { description = "应用服务器的EC2实例类型" type = string default = "t3.medium"
validation { condition = can(regex("^[a-z][0-9][.][a-z]+$", var.instance_type)) error_message = "实例类型必须符合AWS实例类型的有效格式。" } }
variable "enable_monitoring" { description = "为资源启用详细监控" type = bool default = true }
variable "min_instances" { description = "自动扩缩容组中的最小实例数" type = number default = 2
validation { condition = var.min_instances >= 1 && var.min_instances <= 100 error_message = "最小实例数必须在1到100之间。" } }
variable "max_instances" { description = "自动扩缩容组中的最大实例数" type = number default = 10
validation { condition = var.max_instances >= 1 && var.max_instances <= 100 error_message = "最大实例数必须在1到100之间。" } }
undefined

Complex Variable Types

复杂变量类型

hcl
undefined
hcl
undefined

Object type with optional attributes

含可选属性的对象类型

variable "vpc_config" { description = "VPC configuration for the module" type = object({ vpc_id = string subnet_ids = list(string) security_group_ids = optional(list(string), []) assign_public_ip = optional(bool, false) })
validation { condition = length(var.vpc_config.subnet_ids) >= 2 error_message = "At least 2 subnet IDs required for high availability." } }
variable "vpc_config" { description = "模块的VPC配置" type = object({ vpc_id = string subnet_ids = list(string) security_group_ids = optional(list(string), []) assign_public_ip = optional(bool, false) })
validation { condition = length(var.vpc_config.subnet_ids) >= 2 error_message = "为实现高可用性,至少需要2个子网ID。" } }

Map with specific value types

特定值类型的映射

variable "tags" { description = "Additional tags to apply to all resources" type = map(string) default = {}
validation { condition = alltrue([for k, v in var.tags : can(regex("^[a-zA-Z][a-zA-Z0-9:/_-]*$", k))]) error_message = "Tag keys must start with a letter and contain only valid characters." } }
variable "tags" { description = "应用于所有资源的附加标签" type = map(string) default = {}
validation { condition = alltrue([for k, v in var.tags : can(regex("^[a-zA-Z][a-zA-Z0-9:/_-]*$", k))]) error_message = "标签键必须以字母开头,且仅包含有效字符。" } }

List of objects

对象列表

variable "ingress_rules" { description = "List of ingress rules for the security group" type = list(object({ description = string from_port = number to_port = number protocol = string cidr_blocks = optional(list(string), []) security_groups = optional(list(string), []) })) default = []
validation { condition = alltrue([ for rule in var.ingress_rules : rule.from_port >= 0 && rule.from_port <= 65535 && rule.to_port >= 0 && rule.to_port <= 65535 ]) error_message = "Port numbers must be between 0 and 65535." } }
variable "ingress_rules" { description = "安全组的入站规则列表" type = list(object({ description = string from_port = number to_port = number protocol = string cidr_blocks = optional(list(string), []) security_groups = optional(list(string), []) })) default = []
validation { condition = alltrue([ for rule in var.ingress_rules : rule.from_port >= 0 && rule.from_port <= 65535 && rule.to_port >= 0 && rule.to_port <= 65535 ]) error_message = "端口号必须在0到65535之间。" } }

Sensitive variables

敏感变量

variable "database_password" { description = "Master password for the RDS instance" type = string sensitive = true
validation { condition = length(var.database_password) >= 16 error_message = "Database password must be at least 16 characters." } }

---
variable "database_password" { description = "RDS实例的主密码" type = string sensitive = true
validation { condition = length(var.database_password) >= 16 error_message = "数据库密码长度至少为16个字符。" } }

---

Local Values

本地值

locals.tf Template

locals.tf 模板

hcl
locals {
  # Naming convention
  name_prefix = "${var.name}-${var.environment}"

  # Common tags applied to all resources
  common_tags = merge(
    var.tags,
    {
      Name        = local.name_prefix
      Environment = var.environment
      ManagedBy   = "terraform"
      Module      = "my-module"
      Project     = var.name
    }
  )

  # Computed values
  is_production      = var.environment == "prod"
  enable_encryption  = local.is_production
  backup_retention   = local.is_production ? 30 : 7
  instance_count     = local.is_production ? var.max_instances : var.min_instances

  # Derived configurations
  monitoring_config = {
    enabled         = var.enable_monitoring || local.is_production
    detailed        = local.is_production
    retention_days  = local.is_production ? 90 : 30
    alarm_threshold = local.is_production ? 80 : 90
  }

  # Dynamic block helpers
  ingress_rules_map = {
    for idx, rule in var.ingress_rules :
    "${rule.protocol}-${rule.from_port}-${rule.to_port}" => rule
  }

  # Conditional resource naming
  bucket_name = var.bucket_name != null ? var.bucket_name : "${local.name_prefix}-storage-${random_id.bucket.hex}"
}

hcl
locals {
  # 命名规范
  name_prefix = "${var.name}-${var.environment}"

  # 应用于所有资源的通用标签
  common_tags = merge(
    var.tags,
    {
      Name        = local.name_prefix
      Environment = var.environment
      ManagedBy   = "terraform"
      Module      = "my-module"
      Project     = var.name
    }
  )

  # 计算值
  is_production      = var.environment == "prod"
  enable_encryption  = local.is_production
  backup_retention   = local.is_production ? 30 : 7
  instance_count     = local.is_production ? var.max_instances : var.min_instances

  # 派生配置
  monitoring_config = {
    enabled         = var.enable_monitoring || local.is_production
    detailed        = local.is_production
    retention_days  = local.is_production ? 90 : 30
    alarm_threshold = local.is_production ? 80 : 90
  }

  # 动态块助手
  ingress_rules_map = {
    for idx, rule in var.ingress_rules :
    "${rule.protocol}-${rule.from_port}-${rule.to_port}" => rule
  }

  # 条件资源命名
  bucket_name = var.bucket_name != null ? var.bucket_name : "${local.name_prefix}-storage-${random_id.bucket.hex}"
}

Resource Definitions

资源定义

main.tf Template

main.tf 模板

hcl
undefined
hcl
undefined

main.tf

main.tf

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------

Security Group

安全组

#------------------------------------------------------------------------------ resource "aws_security_group" "this" { name_prefix = "${local.name_prefix}-sg-" description = "Security group for ${var.name} ${var.environment}" vpc_id = var.vpc_config.vpc_id
tags = merge(local.common_tags, { Name = "${local.name_prefix}-sg" })
lifecycle { create_before_destroy = true } }
resource "aws_security_group_rule" "ingress" { for_each = local.ingress_rules_map
type = "ingress" security_group_id = aws_security_group.this.id description = each.value.description from_port = each.value.from_port to_port = each.value.to_port protocol = each.value.protocol cidr_blocks = length(each.value.cidr_blocks) > 0 ? each.value.cidr_blocks : null source_security_group_id = length(each.value.security_groups) > 0 ? each.value.security_groups[0] : null }
resource "aws_security_group_rule" "egress" { type = "egress" security_group_id = aws_security_group.this.id description = "Allow all outbound traffic" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------ resource "aws_security_group" "this" { name_prefix = "${local.name_prefix}-sg-" description = "${var.name} ${var.environment}环境的安全组" vpc_id = var.vpc_config.vpc_id
tags = merge(local.common_tags, { Name = "${local.name_prefix}-sg" })
lifecycle { create_before_destroy = true } }
resource "aws_security_group_rule" "ingress" { for_each = local.ingress_rules_map
type = "ingress" security_group_id = aws_security_group.this.id description = each.value.description from_port = each.value.from_port to_port = each.value.to_port protocol = each.value.protocol cidr_blocks = length(each.value.cidr_blocks) > 0 ? each.value.cidr_blocks : null source_security_group_id = length(each.value.security_groups) > 0 ? each.value.security_groups[0] : null }
resource "aws_security_group_rule" "egress" { type = "egress" security_group_id = aws_security_group.this.id description = "允许所有出站流量" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] }
#------------------------------------------------------------------------------

Launch Template

启动模板

#------------------------------------------------------------------------------ resource "aws_launch_template" "this" { name_prefix = "${local.name_prefix}-lt-" description = "Launch template for ${var.name} ${var.environment}" image_id = data.aws_ami.amazon_linux.id instance_type = var.instance_type
network_interfaces { associate_public_ip_address = var.vpc_config.assign_public_ip security_groups = concat([aws_security_group.this.id], var.vpc_config.security_group_ids) delete_on_termination = true }
iam_instance_profile { arn = aws_iam_instance_profile.this.arn }
monitoring { enabled = local.monitoring_config.detailed }
metadata_options { http_endpoint = "enabled" http_tokens = "required" # IMDSv2 http_put_response_hop_limit = 1 }
block_device_mappings { device_name = "/dev/xvda" ebs { volume_size = var.root_volume_size volume_type = "gp3" encrypted = local.enable_encryption kms_key_id = local.enable_encryption ? var.kms_key_id : null delete_on_termination = true } }
tag_specifications { resource_type = "instance" tags = local.common_tags }
tag_specifications { resource_type = "volume" tags = local.common_tags }
tags = local.common_tags
lifecycle { create_before_destroy = true } }
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------ resource "aws_launch_template" "this" { name_prefix = "${local.name_prefix}-lt-" description = "${var.name} ${var.environment}环境的启动模板" image_id = data.aws_ami.amazon_linux.id instance_type = var.instance_type
network_interfaces { associate_public_ip_address = var.vpc_config.assign_public_ip security_groups = concat([aws_security_group.this.id], var.vpc_config.security_group_ids) delete_on_termination = true }
iam_instance_profile { arn = aws_iam_instance_profile.this.arn }
monitoring { enabled = local.monitoring_config.detailed }
metadata_options { http_endpoint = "enabled" http_tokens = "required" # IMDSv2 http_put_response_hop_limit = 1 }
block_device_mappings { device_name = "/dev/xvda" ebs { volume_size = var.root_volume_size volume_type = "gp3" encrypted = local.enable_encryption kms_key_id = local.enable_encryption ? var.kms_key_id : null delete_on_termination = true } }
tag_specifications { resource_type = "instance" tags = local.common_tags }
tag_specifications { resource_type = "volume" tags = local.common_tags }
tags = local.common_tags
lifecycle { create_before_destroy = true } }
#------------------------------------------------------------------------------

Auto Scaling Group

自动扩缩容组

#------------------------------------------------------------------------------ resource "aws_autoscaling_group" "this" { name_prefix = "${local.name_prefix}-asg-" desired_capacity = var.desired_instances min_size = var.min_instances max_size = var.max_instances vpc_zone_identifier = var.vpc_config.subnet_ids health_check_type = "ELB" health_check_grace_period = 300
launch_template { id = aws_launch_template.this.id version = "$Latest" }
dynamic "tag" { for_each = local.common_tags content { key = tag.key value = tag.value propagate_at_launch = true } }
lifecycle { create_before_destroy = true ignore_changes = [desired_capacity] } }

---
#------------------------------------------------------------------------------ resource "aws_autoscaling_group" "this" { name_prefix = "${local.name_prefix}-asg-" desired_capacity = var.desired_instances min_size = var.min_instances max_size = var.max_instances vpc_zone_identifier = var.vpc_config.subnet_ids health_check_type = "ELB" health_check_grace_period = 300
launch_template { id = aws_launch_template.this.id version = "$Latest" }
dynamic "tag" { for_each = local.common_tags content { key = tag.key value = tag.value propagate_at_launch = true } }
lifecycle { create_before_destroy = true ignore_changes = [desired_capacity] } }

---

Data Sources

数据源

data.tf Template

data.tf 模板

hcl
undefined
hcl
undefined

data.tf

data.tf

Get current AWS account info

获取当前AWS账户信息

data "aws_caller_identity" "current" {} data "aws_region" "current" {} data "aws_partition" "current" {}
data "aws_caller_identity" "current" {} data "aws_region" "current" {} data "aws_partition" "current" {}

Get latest Amazon Linux 2023 AMI

获取最新的Amazon Linux 2023 AMI

data "aws_ami" "amazon_linux" { most_recent = true owners = ["amazon"]
filter { name = "name" values = ["al2023-ami-*-x86_64"] }
filter { name = "virtualization-type" values = ["hvm"] }
filter { name = "architecture" values = ["x86_64"] } }
data "aws_ami" "amazon_linux" { most_recent = true owners = ["amazon"]
filter { name = "name" values = ["al2023-ami-*-x86_64"] }
filter { name = "virtualization-type" values = ["hvm"] }
filter { name = "architecture" values = ["x86_64"] } }

Get VPC info if not provided

获取VPC信息(若未提供)

data "aws_vpc" "selected" { id = var.vpc_config.vpc_id }
data "aws_vpc" "selected" { id = var.vpc_config.vpc_id }

Get subnet info for AZ distribution

获取子网信息用于可用区分布

data "aws_subnet" "selected" { for_each = toset(var.vpc_config.subnet_ids) id = each.value }
data "aws_subnet" "selected" { for_each = toset(var.vpc_config.subnet_ids) id = each.value }

Get available AZs

获取可用可用区

data "aws_availability_zones" "available" { state = "available" filter { name = "opt-in-status" values = ["opt-in-not-required"] } }

---
data "aws_availability_zones" "available" { state = "available" filter { name = "opt-in-status" values = ["opt-in-not-required"] } }

---

Output Definitions

输出定义

outputs.tf Template

outputs.tf 模板

hcl
undefined
hcl
undefined

outputs.tf

outputs.tf

#------------------------------------------------------------------------------
#------------------------------------------------------------------------------

Primary Outputs

核心输出

#------------------------------------------------------------------------------ output "id" { description = "The unique identifier for this module instance" value = aws_autoscaling_group.this.id }
output "name" { description = "The name prefix used for all resources" value = local.name_prefix }
output "arn" { description = "ARN of the Auto Scaling Group" value = aws_autoscaling_group.this.arn }
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------ output "id" { description = "本模块实例的唯一标识符" value = aws_autoscaling_group.this.id }
output "name" { description = "用于所有资源的名称前缀" value = local.name_prefix }
output "arn" { description = "自动扩缩容组的ARN" value = aws_autoscaling_group.this.arn }
#------------------------------------------------------------------------------

Security Group Outputs

安全组输出

#------------------------------------------------------------------------------ output "security_group_id" { description = "ID of the security group created for this module" value = aws_security_group.this.id }
output "security_group_arn" { description = "ARN of the security group" value = aws_security_group.this.arn }
output "security_group_name" { description = "Name of the security group" value = aws_security_group.this.name }
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------ output "security_group_id" { description = "为本模块创建的安全组ID" value = aws_security_group.this.id }
output "security_group_arn" { description = "安全组的ARN" value = aws_security_group.this.arn }
output "security_group_name" { description = "安全组的名称" value = aws_security_group.this.name }
#------------------------------------------------------------------------------

Launch Template Outputs

启动模板输出

#------------------------------------------------------------------------------ output "launch_template_id" { description = "ID of the launch template" value = aws_launch_template.this.id }
output "launch_template_arn" { description = "ARN of the launch template" value = aws_launch_template.this.arn }
output "launch_template_latest_version" { description = "Latest version of the launch template" value = aws_launch_template.this.latest_version }
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------ output "launch_template_id" { description = "启动模板的ID" value = aws_launch_template.this.id }
output "launch_template_arn" { description = "启动模板的ARN" value = aws_launch_template.this.arn }
output "launch_template_latest_version" { description = "启动模板的最新版本" value = aws_launch_template.this.latest_version }
#------------------------------------------------------------------------------

Computed/Derived Outputs

计算/派生输出

#------------------------------------------------------------------------------ output "ami_id" { description = "ID of the AMI used for instances" value = data.aws_ami.amazon_linux.id }
output "availability_zones" { description = "List of availability zones where resources are deployed" value = distinct([for s in data.aws_subnet.selected : s.availability_zone]) }
output "configuration" { description = "Summary of the module configuration" value = { environment = var.environment instance_type = var.instance_type min_instances = var.min_instances max_instances = var.max_instances monitoring_enabled = local.monitoring_config.enabled encryption_enabled = local.enable_encryption } }
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------ output "ami_id" { description = "用于实例的AMI ID" value = data.aws_ami.amazon_linux.id }
output "availability_zones" { description = "资源部署的可用区列表" value = distinct([for s in data.aws_subnet.selected : s.availability_zone]) }
output "configuration" { description = "模块配置摘要" value = { environment = var.environment instance_type = var.instance_type min_instances = var.min_instances max_instances = var.max_instances monitoring_enabled = local.monitoring_config.enabled encryption_enabled = local.enable_encryption } }
#------------------------------------------------------------------------------

Sensitive Outputs

敏感输出

#------------------------------------------------------------------------------ output "iam_role_arn" { description = "ARN of the IAM role attached to instances" value = aws_iam_role.this.arn sensitive = false }

---
#------------------------------------------------------------------------------ output "iam_role_arn" { description = "附加到实例的IAM角色ARN" value = aws_iam_role.this.arn sensitive = false }

---

Conditional Resource Creation

条件资源创建

Using count vs for_each

使用count vs for_each

hcl
undefined
hcl
undefined

Use count for simple on/off toggles

简单开关使用count

resource "aws_cloudwatch_metric_alarm" "high_cpu" { count = var.enable_monitoring ? 1 : 0
alarm_name = "${local.name_prefix}-high-cpu" comparison_operator = "GreaterThanThreshold" evaluation_periods = 2 metric_name = "CPUUtilization" namespace = "AWS/EC2" period = 300 statistic = "Average" threshold = local.monitoring_config.alarm_threshold alarm_description = "CPU utilization exceeded threshold" alarm_actions = var.alarm_actions
dimensions = { AutoScalingGroupName = aws_autoscaling_group.this.name }
tags = local.common_tags }
resource "aws_cloudwatch_metric_alarm" "high_cpu" { count = var.enable_monitoring ? 1 : 0
alarm_name = "${local.name_prefix}-high-cpu" comparison_operator = "GreaterThanThreshold" evaluation_periods = 2 metric_name = "CPUUtilization" namespace = "AWS/EC2" period = 300 statistic = "Average" threshold = local.monitoring_config.alarm_threshold alarm_description = "CPU使用率超过阈值" alarm_actions = var.alarm_actions
dimensions = { AutoScalingGroupName = aws_autoscaling_group.this.name }
tags = local.common_tags }

Use for_each for collections

集合类资源使用for_each

resource "aws_s3_bucket" "logs" { for_each = var.enable_logging ? toset(["access", "audit", "error"]) : toset([])
bucket = "${local.name_prefix}-${each.key}-logs"
tags = merge(local.common_tags, { LogType = each.key }) }
resource "aws_s3_bucket" "logs" { for_each = var.enable_logging ? toset(["access", "audit", "error"]) : toset([])
bucket = "${local.name_prefix}-${each.key}-logs"
tags = merge(local.common_tags, { LogType = each.key }) }

for_each with complex objects

复杂对象使用for_each

resource "aws_route53_record" "this" { for_each = { for record in var.dns_records : "${record.name}-${record.type}" => record }
zone_id = var.route53_zone_id name = each.value.name type = each.value.type ttl = each.value.ttl records = each.value.records }

---
resource "aws_route53_record" "this" { for_each = { for record in var.dns_records : "${record.name}-${record.type}" => record }
zone_id = var.route53_zone_id name = each.value.name type = each.value.type ttl = each.value.ttl records = each.value.records }

---

Module Composition

模块组合

Root Module Example

根模块示例

hcl
undefined
hcl
undefined

examples/complete/main.tf

examples/complete/main.tf

terraform { required_version = ">= 1.5.0" }
provider "aws" { region = var.region }
terraform { required_version = ">= 1.5.0" }
provider "aws" { region = var.region }

Network module

网络模块

module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 5.0"
name = "${var.name}-vpc" cidr = "10.0.0.0/16"
azs = ["${var.region}a", "${var.region}b", "${var.region}c"] private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true single_nat_gateway = var.environment != "prod"
tags = var.tags }
module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 5.0"
name = "${var.name}-vpc" cidr = "10.0.0.0/16"
azs = ["${var.region}a", "${var.region}b", "${var.region}c"] private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true single_nat_gateway = var.environment != "prod"
tags = var.tags }

Application module

应用模块

module "app" { source = "../../"
name = var.name environment = var.environment
vpc_config = { vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets }
instance_type = var.instance_type min_instances = var.min_instances max_instances = var.max_instances enable_monitoring = true
ingress_rules = [ { description = "HTTP from ALB" from_port = 80 to_port = 80 protocol = "tcp" security_groups = [module.alb.security_group_id] } ]
tags = var.tags }
module "app" { source = "../../"
name = var.name environment = var.environment
vpc_config = { vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets }
instance_type = var.instance_type min_instances = var.min_instances max_instances = var.max_instances enable_monitoring = true
ingress_rules = [ { description = "来自ALB的HTTP流量" from_port = 80 to_port = 80 protocol = "tcp" security_groups = [module.alb.security_group_id] } ]
tags = var.tags }

ALB module

ALB模块

module "alb" { source = "terraform-aws-modules/alb/aws" version = "~> 8.0"
name = "${var.name}-alb" load_balancer_type = "application" vpc_id = module.vpc.vpc_id subnets = module.vpc.public_subnets
target_groups = [ { name = "${var.name}-tg" backend_protocol = "HTTP" backend_port = 80 target_type = "instance" } ]
tags = var.tags }
module "alb" { source = "terraform-aws-modules/alb/aws" version = "~> 8.0"
name = "${var.name}-alb" load_balancer_type = "application" vpc_id = module.vpc.vpc_id subnets = module.vpc.public_subnets
target_groups = [ { name = "${var.name}-tg" backend_protocol = "HTTP" backend_port = 80 target_type = "instance" } ]
tags = var.tags }

Outputs

输出

output "vpc_id" { value = module.vpc.vpc_id }
output "app_security_group_id" { value = module.app.security_group_id }
output "alb_dns_name" { value = module.alb.lb_dns_name }

---
output "vpc_id" { value = module.vpc.vpc_id }
output "app_security_group_id" { value = module.app.security_group_id }
output "alb_dns_name" { value = module.alb.lb_dns_name }

---

Documentation

文档

README.md Template

README.md 模板

markdown
undefined
markdown
undefined

Module Name

模块名称

Brief description of what this module creates.
本模块创建资源的简要说明。

Features

特性

  • Feature 1
  • Feature 2
  • Feature 3
  • 特性1
  • 特性2
  • 特性3

Usage

使用方法

Basic

基础用法

hcl
module "example" {
  source = "github.com/org/terraform-aws-module?ref=v1.0.0"

  name        = "my-app"
  environment = "prod"

  vpc_config = {
    vpc_id     = "vpc-12345678"
    subnet_ids = ["subnet-1", "subnet-2"]
  }
}
hcl
module "example" {
  source = "github.com/org/terraform-aws-module?ref=v1.0.0"

  name        = "my-app"
  environment = "prod"

  vpc_config = {
    vpc_id     = "vpc-12345678"
    subnet_ids = ["subnet-1", "subnet-2"]
  }
}

Advanced

高级用法

hcl
module "example" {
  source = "github.com/org/terraform-aws-module?ref=v1.0.0"

  name        = "my-app"
  environment = "prod"

  vpc_config = {
    vpc_id             = "vpc-12345678"
    subnet_ids         = ["subnet-1", "subnet-2"]
    security_group_ids = ["sg-existing"]
    assign_public_ip   = false
  }

  instance_type     = "t3.large"
  min_instances     = 3
  max_instances     = 10
  enable_monitoring = true

  ingress_rules = [
    {
      description = "HTTPS"
      from_port   = 443
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = ["10.0.0.0/8"]
    }
  ]

  tags = {
    Team    = "platform"
    CostCenter = "12345"
  }
}
hcl
module "example" {
  source = "github.com/org/terraform-aws-module?ref=v1.0.0"

  name        = "my-app"
  environment = "prod"

  vpc_config = {
    vpc_id             = "vpc-12345678"
    subnet_ids         = ["subnet-1", "subnet-2"]
    security_group_ids = ["sg-existing"]
    assign_public_ip   = false
  }

  instance_type     = "t3.large"
  min_instances     = 3
  max_instances     = 10
  enable_monitoring = true

  ingress_rules = [
    {
      description = "HTTPS流量"
      from_port   = 443
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = ["10.0.0.0/8"]
    }
  ]

  tags = {
    Team    = "platform"
    CostCenter = "12345"
  }
}

Requirements

依赖要求

NameVersion
terraform>= 1.5.0
aws>= 5.0.0, < 6.0.0
名称版本
terraform>= 1.5.0
aws>= 5.0.0, < 6.0.0

Providers

提供商

NameVersion
aws>= 5.0.0
名称版本
aws>= 5.0.0

Inputs

输入参数

NameDescriptionTypeDefaultRequired
nameName prefix for resources
string
n/ayes
environmentEnvironment (dev/staging/prod)
string
n/ayes
vpc_configVPC configuration
object
n/ayes
instance_typeEC2 instance type
string
"t3.medium"
no
min_instancesMinimum ASG size
number
2
no
max_instancesMaximum ASG size
number
10
no
名称说明类型默认值是否必填
name资源名称前缀
string
n/a
environment环境(dev/staging/prod)
string
n/a
vpc_configVPC配置
object
n/a
instance_typeEC2实例类型
string
"t3.medium"
min_instancesASG最小规模
number
2
max_instancesASG最大规模
number
10

Outputs

输出参数

NameDescription
idAuto Scaling Group ID
security_group_idSecurity Group ID
launch_template_idLaunch Template ID
名称说明
id自动扩缩容组ID
security_group_id安全组ID
launch_template_id启动模板ID

License

许可证

MIT

---
MIT

---

Лучшие практики

最佳实践

  1. Используй версионирование — семантическое версионирование для модулей
  2. Валидируй входные переменные — используй validation blocks
  3. Документируй всё — описания для variables и outputs
  4. Избегай hardcoded значений — всё должно быть configurable
  5. Используй for_each вместо count — лучше управление state
  6. Группируй связанные ресурсы — логическая организация main.tf
  7. Тестируй модули — используй terratest или terraform test
  8. Следуй naming conventions — консистентное именование ресурсов
  1. 使用版本控制 — 为模块采用语义化版本控制
  2. 验证输入变量 — 使用validation块
  3. 全面文档化 — 为variables和outputs添加描述
  4. 避免硬编码值 — 所有配置项应支持自定义
  5. 优先使用for_each而非count — 更优的状态管理
  6. 分组关联资源 — 按逻辑组织main.tf
  7. 测试模块 — 使用terratest或terraform test
  8. 遵循命名规范 — 资源命名保持一致性