3. 服务目录架构设计:模块化设计原则
服务目录(Service Catalog)是 Terraform 工作流优化的核心资产。它将基础设施从“一次性脚本”转变为“可复用的产品”。本章聚焦于如何通过模块化设计原则,将基础设施抽象为标准化、可组合的服务目录项,从而提升执行效率与团队协作水平。
3.1 模块化设计的三大核心原则
在构建服务目录时,必须遵循以下原则,确保每个模块独立、可测试且易于组合:
| 原则 | 描述 | 关键实践 |
|---|---|---|
| 单一职责 | 每个模块只负责一种基础设施资源或一个逻辑单元(如:一个 VPC、一个 RDS 实例)。 | 避免创建“万能模块”;模块名称应直接反映其职责,如 aws-vpc、aws-ecs-service。 |
| 显式接口 | 通过输入变量(Input Variables)和输出值(Output Values)定义清晰的契约。 | 所有依赖必须通过变量传递;禁止在模块内部硬编码环境差异。 |
| 可组合性 | 模块应像乐高积木一样,能够通过根模块(Root Module)或编排层自由组合。 | 模块之间不产生隐式依赖;通过 Terraform 的 depends_on 或数据源显式声明关系。 |
实践提示: 在模块的 README 中明确标注“输入变量默认值仅用于开发环境”,避免生产环境误用默认配置。
3.2 服务目录的抽象层次模型
将基础设施抽象为服务目录项,通常分为三个层次。下图展示了从底层资源到上层业务服务的映射关系:
架构要点: 基础模块层是“砖块”,服务目录项是“房间”,业务服务层是“整栋楼”。每一层只依赖下一层提供的接口,不跨层调用。
3.3 模块结构标准化:服务目录项模板
每个服务目录项应遵循统一的文件结构,降低认知成本。推荐的标准布局如下:
service-catalog/
├── terraform-aws-standard-webapp/ # 服务目录项名称
│ ├── README.md # 使用说明、输入输出、示例
│ ├── main.tf # 主逻辑,调用基础模块
│ ├── variables.tf # 输入变量定义
│ ├── outputs.tf # 输出值定义
│ ├── versions.tf # Terraform 与 Provider 版本约束
│ ├── examples/
│ │ └── basic-usage/ # 可运行的示例
│ │ ├── main.tf
│ │ └── terraform.tfvars
│ └── tests/ # 自动化测试(Terratest 等)
│ └── webapp_test.go
常见反模式: 将
terraform.tfvars 或 backend.tf 硬编码在模块内部。这些文件应属于调用方,而非模块本身。
3.4 变量与输出设计规范
良好的接口设计是模块复用的基石。下表对比了推荐与不推荐的变量设计方式:
| 设计维度 | 推荐做法 | 不推荐做法 |
|---|---|---|
| 变量命名 | 使用清晰、自解释的名称,如 vpc_cidr_block |
使用缩写或模糊名称,如 cidr、cfg |
| 默认值 | 提供安全的开发环境默认值,并注释说明 | 不提供默认值,或提供生产级高风险默认值 |
| 类型约束 | 使用 string、number、list(string) 等具体类型 |
滥用 any 类型,导致接口不明确 |
| 验证规则 | 使用 validation 块检查 CIDR 格式、端口范围等 |
依赖文档或口头约定,无代码级校验 |
| 输出值 | 输出模块内创建的关键资源属性(如 ID、ARN、端点) | 输出所有资源属性,造成信息过载 |
3.5 模块组合与依赖管理
服务目录项通常由多个基础模块组合而成。下图展示了一个“标准 Web 应用栈”服务目录项的内部组合关系:
3.6 版本管理与发布策略
服务目录项应使用语义化版本控制(SemVer),并与 Git Tag 绑定。推荐的工作流如下:
- 开发阶段: 在模块仓库的
main分支进行迭代,版本号为0.x.y。 - 预发布: 创建 Release Candidate 分支,运行集成测试套件。
- 正式发布: 合并至
main,打 Tag 如v1.2.0,并更新服务目录索引文件。 - 消费端锁定: 在根模块中通过
source = "git::https://...//terraform-aws-standard-webapp?ref=v1.2.0"锁定版本。
效率提升关键: 使用
terraform init -upgrade 仅在有明确升级意图时更新模块版本,避免“隐式升级”导致生产环境意外变更。
3.7 服务目录索引与发现
当服务目录项数量超过 10 个时,建议维护一个中央索引文件(如 catalog.yaml),供团队快速检索和消费:
# catalog.yaml
catalog_items:
- name: standard-webapp
description: 标准 Web 应用栈,包含 VPC、ECS Fargate、RDS
version: "1.2.0"
source: "git::https://github.com/org/terraform-aws-standard-webapp?ref=v1.2.0"
tags: ["web", "ecs", "rds", "production-ready"]
- name: serverless-api
description: 无服务器 API,基于 API Gateway + Lambda + DynamoDB
version: "0.4.1"
source: "git::https://github.com/org/terraform-aws-serverless-api?ref=v0.4.1"
tags: ["serverless", "api", "low-cost"]
通过自动化工具(如 terragrunt 或自定义脚本)解析该索引,可快速生成调用代码骨架,将新服务的部署时间从小时级缩短到分钟级。