在 Terraform 项目上实施端到端 Terratest 测试

使用 Terraform 可以定义、预览和部署云基础结构。 使用 Terraform 时,请使用 HCL 语法来创建配置文件。 HCL 语法允许你指定云提供商(如 Azure)和构成云基础结构的元素。 创建配置文件后,请创建一个执行计划,利用该计划,可在部署基础结构更改之前先预览这些更改。 验证更改后,应用执行计划来部署基础结构。

端到端 (E2E) 测试用于在将程序部署到生产环境之前验证程序是否正常工作。 例如,Terraform 模块可将两个虚拟机部署到虚拟网络。 你可能想要阻止这两台计算机互相发送ping命令。 在此示例中,可以定义一个测试来验证部署前的预期结果。

E2E 测试通常是一个三步过程。

  1. 将配置应用于测试环境。
  2. 运行代码以验证结果。
  3. 测试环境要么重新初始化,要么关闭(例如解除分配虚拟机)。

在这篇文章中,你将学会如何:

  • 了解使用 Terratest 进行端到端测试的基础知识
  • 了解如何使用 Golang 编写端到端测试
  • 了解如何在将代码提交到存储库时使用 Azure DevOps 自动触发端到端测试

1.配置环境

  • Azure 订阅:如果没有 Azure 订阅,请在开始之前创建 一个免费帐户
  • Go 编程语言安装 Go

  • 示例代码和资源: 使用 DownGit 工具,从 GitHub 下载 端到端测试项目 ,并解压缩到新目录中以包含示例代码。 此目录称为 示例目录

2. 了解端到端测试

端到端测试验证系统作为一个整体工作。 这种类型的测试与测试特定模块相反。 对于 Terraform 项目,端到端测试允许验证已部署的内容。 这种类型的测试不同于测试部署前方案的许多其他类型的测试。 端到端测试对于测试包含多个模块并作用于多个资源的复杂系统至关重要。 在这种情况下,端到端测试是确定各个模块是否正确交互的唯一方法。

本文重点介绍如何使用 Terratest 实现端到端测试。 Terratest 提供了执行以下任务所需的所有管道:

  • 部署 Terraform 配置
  • 使您能够使用 Go 语言编写测试来验证已部署的内容
  • 将测试编排到各个阶段
  • 拆除已部署的基础设施

3. 了解测试示例

在本文中,我们将使用 Azure/terraform 示例存储库中提供的示例。

此示例定义了一个 Terraform 配置,该配置将两个 Linux 虚拟机部署到同一个虚拟网络中。 一个名为 - 的 vm-linux-1 VM 具有公共 IP 地址。 仅打开端口 22 以允许 SSH 连接。 第二个 VM - vm-linux-2 - 没有定义的公共 IP 地址。

该测试验证以下场景:

  • 基础架构部署正确
  • 使用端口 22,可以打开 SSH 会话以 vm-linux-1
  • 在 上使用 SSH 会话 vm-linux-1,可以 ping vm-linux-2

端到端测试场景示例

如果您 下载了示例,则可以在 src/main.tf 文件中找到此方案的 Terraform 配置。 该文件 main.tf 包含部署上图所示的 Azure 基础结构所需的一切。

如果不熟悉如何创建虚拟机,请参阅 使用 Terraform 在 Azure 中创建具有基础结构的 Linux VM

谨慎

本文中提供的示例场景仅用于说明目的。 我们特意让事情变得简单,以便专注于端到端测试的步骤。 我们不建议使用通过公共 IP 地址公开 SSH 端口的生产虚拟机。

4. 检查测试示例

端到端测试使用 Go 语言编写,并使用 Terratest 框架。 如果您 下载了示例,则会在 src/test/end2end_test.go 文件中定义测试。

以下源代码显示了使用 Terratest 的 Golang 测试的标准结构:

package test

import (
    "testing"

    "github.com/gruntwork-io/terratest/modules/terraform"
    test_structure "github.com/gruntwork-io/terratest/modules/test-structure"
)

func TestEndToEndDeploymentScenario(t *testing.T) {
    t.Parallel()

    fixtureFolder := "../"

    // Use Terratest to deploy the infrastructure
    test_structure.RunTestStage(t, "setup", func() {
        terraformOptions := &terraform.Options{
            // Indicate the directory that contains the Terraform configuration to deploy
            TerraformDir: fixtureFolder,
        }

        // Save options for later test stages
        test_structure.SaveTerraformOptions(t, fixtureFolder, terraformOptions)

        // Triggers the terraform init and terraform apply command
        terraform.InitAndApply(t, terraformOptions)
    })

    test_structure.RunTestStage(t, "validate", func() {
        // run validation checks here
        terraformOptions := test_structure.LoadTerraformOptions(t, fixtureFolder)
		    publicIpAddress := terraform.Output(t, terraformOptions, "public_ip_address")
    })

    // When the test is completed, teardown the infrastructure by calling terraform destroy
    test_structure.RunTestStage(t, "teardown", func() {
        terraformOptions := test_structure.LoadTerraformOptions(t, fixtureFolder)
        terraform.Destroy(t, terraformOptions)
    })
}

如前面的代码片段所示,测试由三个阶段组成:

  • setup:运行 Terraform 以部署配置
  • validate':执行验证检查和断言
  • teardown:在测试运行后清理基础设施

Terratest 框架提供的一些关键功能如下:

  • terraform 的InitAndApply:启用运行 terraform init Go 代码和 terraform apply 从 Go 代码
  • terraform 的Output:检索部署输出变量的值。
  • terraform 的销毁:从 Go 代码运行 terraform destroy 命令。
  • test_structure。LoadTerraformOptions:从状态加载 Terraform 选项(例如配置和变量)
  • test_structure。SaveTerraformOptions:将 Terraform 选项(例如配置和变量)保存到状态

5. 运行测试示例

以下步骤针对示例配置和部署运行测试。

  1. 打开 bash/terminal 窗口。

  2. 登录到 Azure 帐户。

  3. 要运行此示例测试,您需要 SSH 私有/公有密钥对名称 id_rsa ,并 id_rsa.pub 位于您的主目录中。 替换为 <your_user_name> 您的主目录的名称。

    export TEST_SSH_KEY_PATH="~/.ssh/id_rsa"
    
  4. 在示例目录中,导航到 src/test 目录。

  5. 运行测试。

    go test -v ./ -timeout 10m
    

6. 验证结果

成功运行 go test后,您会看到类似于以下输出的结果:

--- PASS: TestEndToEndDeploymentScenario (390.99s)
PASS
ok      test    391.052s

Azure 上的 Terraform 故障排除

排查在 Azure 上使用 Terraform 时遇到的常见问题

后续步骤