本文档提供了使用根模块时需要考虑的准则和建议。
根配置或根模块是您在其中运行 Terraform CLI 的工作目录。确保根配置遵循以下标准(以及适用的上述 Terraform 准则)。针对根模块的明确建议取代了一般准则。
本指南未介绍 Terraform。如需了解如何将 Terraform 与 Google Cloud 搭配使用,请参阅 Terraform 使用入门。
最大限度地减少每个根模块中的资源数量
请务必防止单个根配置过大,同时还要防止同一目录和状态下存储的资源过多。每次运行 Terraform 时,特定根配置中的所有资源都会刷新。如果单个状态中包含的资源过多,则可能会导致执行缓慢。一般规则:在单个状态下,不要添加超过 100 个资源(最好不要超过十几个)。
为每个应用使用单独的目录
如需相互独立地管理应用和项目,请将每个应用和项目的资源放在其各自的 Terraform 目录中。服务可能表示特定应用或通用服务,例如共享网络。将特定服务的所有 Terraform 代码嵌套在一个目录(包括子目录)下。
将应用拆分为特定于环境的子目录
在 Google Cloud 中部署服务时,将服务的 Terraform 配置拆分为两个顶级目录:包含服务的实际配置的 modules
目录和包含每个环境的根配置的 environments
目录。
-- SERVICE-DIRECTORY/
-- OWNERS
-- modules/
-- <service-name>/
-- main.tf
-- variables.tf
-- outputs.tf
-- provider.tf
-- README
-- ...other…
-- environments/
-- dev/
-- backend.tf
-- main.tf
-- qa/
-- backend.tf
-- main.tf
-- prod/
-- backend.tf
-- main.tf
使用环境目录
如需跨环境共享代码,请引用模块。通常,这可能是一个服务模块,其中包含服务的基本共享 Terraform 配置。在服务模块中,对常见输入进行硬编码,并且只需要特定于环境的输入作为变量。
每个环境目录必须包含以下文件:
backend.tf
文件,用于声明 Terraform backend状态位置(通常为 Cloud Storage)main.tf
文件,用于实例化服务模块
每个环境目录(dev
、qa
、prod
)对应于默认的 Terraform 工作区,并会将服务版本部署到该环境。这些工作区将特定于环境的资源隔离到各自的上下文中。仅使用默认工作区。
不建议在一个环境中使用多个 CLI 工作区,原因如下:
- 检查每个工作区中的配置并非易事。
- 不建议为多个工作区使用单个共享后端,因为如果将共享后端用于环境分隔,它会成为单点故障。
- 虽然代码可以重复使用,但必须根据当前工作区变量进行切换(例如
terraform.workspace == "foo" ? this : that
),这增加了读取代码的难度。
详情请参阅以下内容:
通过远程状态公开输出
确保您从根模块公开模块实例的有用输出。
例如,以下代码段传递项目工厂模块实例中的项目 ID 输出,将其作为根模块的输出。
# Project root module
terraform {
backend "gcs" {
bucket = "BUCKET"
}
}
module "project" {
source = "terraform-google-modules/project-factory/google"
...
}
output "project_id" {
value = module.project.project_id
description = "The ID of the created project"
}
其他 Terraform 环境和应用只能引用根模块级输出。
通过使用远程状态,您可以引用根模块输出。若要允许其他依赖应用使用配置,请确保将与服务的端点相关的信息导出到远程状态。
# Networks root module
data "terraform_remote_state" "network_project" {
backend = "gcs"
config = {
bucket = "BUCKET"
}
}
module "vpc" {
source = "terraform-google-modules/network/google"
version = "~> 9.0"
project_id = data.terraform_remote_state.network_project.outputs.project_id
network_name = "vpc-1"
...
}
有时,例如,从环境目录调用共享服务模块时,重新导出整个子模块是最适当的操作,如下所示:
output "service" {
value = module.service
description = "The service module outputs"
}
固定到次要提供商版本
在根模块中,声明每个提供商并固定到次要版本。这样可以自动升级升级到新的补丁版本,同时仍保持可靠的目标。 为了保持一致性,请将版本文件命名为 versions.tf
。
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 4.0.0"
}
}
}
将变量存储在 tfvars
文件中
对于根模块,请使用 .tfvars
变量文件提供变量。为了保持一致性,请将变量文件命名为 terraform.tfvars
。
请勿使用替代 var-files
或 var='key=val'
命令行选项指定变量。命令行选项是临时性的,容易忘记。使用默认变量文件更容易预测。
签入 .terraform.lock.hcl
文件
对于根模块,.terraform.lock.hcl
依赖项锁文件应签入源代码控制系统中。这有助于跟踪和审核指定配置的提供商选择变化。