本文档提供了有关测试适用于 Google Cloud 的 Terraform 模块和配置的准则和建议。
测试 Terraform 模块和配置有时会遵循与测试应用代码不同的模式和惯例。虽然测试应用代码主要涉及测试应用本身的业务逻辑,但全面测试基础架构代码需要部署真实的云资源,以最大限度地降低生产失败的风险。运行 Terraform 测试时,需要考虑以下几点:
- 运行 Terraform 测试会创建、修改和销毁实际的基础架构,因此您的测试可能非常耗时且昂贵。
- 您不能只对端到端架构进行单元测试。最佳方法是将架构分解为多个模块并单独进行测试。此方法的好处包括由于测试运行时加快而提高了迭代开发速度,每个测试的费用降低,以及超出控制范围的因素导致测试失败的可能性降低。
- 尽可能避免重复使用状态。在某些情况下,您可能要使用与其他配置共享数据的配置进行测试,但理想情况下,每个测试都应该是独立的,不应在测试之间重复使用状态。
先使用费用较少的测试方法
您可以使用多种方法来测试 Terraform。这些方法按费用、运行时间和深度升序排序,其中包括:
- 静态分析:使用编译器、linter 和试运行等工具测试配置的语法和结构,而无需部署任何资源。为此,请使用
terraform validate
。 - 模块集成测试:为了确保模块正常运行,请单独测试各个模块。模块的集成测试涉及将模块部署到测试环境中并验证是否创建了预期的资源。有几种测试框架可让您更轻松地编写测试,如下所示:
- 端到端测试:通过将集成测试方法扩展到整个环境,您可以确认多个模块能否协同工作。使用此方法可以部署构成新测试环境中架构的所有模块。理想情况下,测试环境与生产环境尽可能相似。这种方法费用昂贵,但可以确信更改不会破坏生产环境。
先从小规模测试开始
确保测试以迭代方式在彼此的基础上进行构建。请考虑先运行较小规模的测试,然后使用快速失败方法进行更复杂的测试。
随机选择项目 ID 和资源名称
为避免命名冲突,请确保您的配置在每个项目中都具有全局唯一的项目 ID 和非重叠的资源名称。为了实现这一目的,请为资源使用命名空间。为此,Terraform 具有内置的随机提供程序。
使用单独的环境进行测试
在测试期间,系统会创建和删除许多资源。确保此环境与开发或生产项目隔离,以避免在资源清理期间发生意外删除。最好的方法是让每个测试都创建一个新项目或文件夹。为避免配置错误,请考虑专门为执行每个测试创建服务账号。
清理所有资源
测试基础架构代码意味着您要部署实际资源。为避免产生费用,请考虑执行清理步骤。
如需销毁由特定配置管理的所有远程对象,请使用 terraform destroy
命令。一些测试框架具有内置的清理步骤。例如,如果您使用的是 Terratest,请将 defer terraform.Destroy(t, terraformOptions)
添加到测试中。如果您使用的是 Kitchen-Terraform,请使用 terraform kitchen delete WORKSPACE_NAME
删除工作区。
运行 terraform destroy
命令后,您还需要运行其他清理过程来移除 Terraform 未能销毁的任何资源。为此,请删除用于测试执行的任何项目或使用 project_cleanup
模块等工具。
优化测试运行时
如需优化测试执行时间,请使用以下方法:
- 并行运行测试。某些测试框架支持同时运行多个 Terraform 测试。
- 例如,您可以使用 Terratest 在测试函数定义后添加
t.Parallel()
来执行此操作。
- 例如,您可以使用 Terratest 在测试函数定义后添加
- 分阶段测试。将测试分为可以单独测试的独立配置。这种方法无需在运行测试时经历所有阶段,并可加快迭代开发周期。
- 例如,在 Kitchen-Terraform 中,将测试拆分为单独的套件。迭代时,独立执行每个套件。
- 同样,可以使用 Terratest 通过
stage(t, STAGE_NAME, CORRESPONDING_TESTFUNCTION)
封装测试的每个阶段。设置环境变量,以指示要运行哪些测试。例如SKIP
STAGE_NAME="true"
。 - 蓝图测试框架支持分阶段执行。