在 Azure 中为 Terraform 项目实现集成测试
使用 Terraform 可以定义、预览和部署云基础结构。 使用 Terraform 时,请使用 HCL 语法来创建配置文件。 利用 HCL 语法,可指定 Azure 这样的云提供程序和构成云基础结构的元素。 创建配置文件后,请创建一个执行计划,利用该计划,可在部署基础结构更改之前先预览这些更改。 验证了更改后,请应用该执行计划以部署基础结构。
集成测试可验证新引入的代码更改是否不会破坏现有代码。 在 DevOps 中,持续集成 (CI) 是指每当代码库发生更改(例如有用户要将 PR 合并到 Git 存储库中)时都生成整个系统的过程。 下表包含集成测试的常见示例:
- 静态代码分析工具,例如 lint 和格式。
- 运行 terraform validate 来验证配置文件的语法。
- 运行 terraform plan 以确保配置将按预期方式工作。
在本文中,学习如何:
- 了解 Terraform 项目的集成测试基础知识。
- 使用 Azure DevOps 配置持续集成管道。
- 对 Terraform 代码运行静态代码分析。
- 运行
terraform validate
以验证本地计算机上的 Terraform 配置文件。 - 运行
terraform plan
,从远程服务的角度验证 Terraform 配置文件。 - 使用 Azure 管道自动进行持续集成。
1.配置环境
- Azure 订阅:如果没有 Azure 订阅,请在开始之前创建一个免费帐户。
配置 Terraform:如果尚未执行此操作,请使用以下选项之一配置 Terraform:
Azure DevOps 组织和项目:如果没有, 请创建 Azure DevOps 组织。
Terraform 生成和发布任务扩展: 将 Terraform 生成/发布任务扩展 安装到 Azure DevOps 组织中。
授予 Azure DevOps 对 Azure 订阅的访问权限:创建一个名为
terraform-basic-testing-azure-connection
允许 Azure Pipelines 连接到 Azure 订阅的 Azure 服务连接示例代码和资源: 从 GitHub 下载集成测试项目。 下载示例的目录称为 示例目录。
2. 验证本地 Terraform 配置
terraform validate 命令是从包含 Terraform 文件的目录中的命令行运行的。 此命令主要用于验证语法。
在示例目录中,导航到
src
目录。运行 terraform init,将工作目录进行初始化。
terraform init
运行 terraform validate 来验证配置文件的语法。
terraform validate
要点:
- 你会看到一条消息,它指出 Terraform 配置有效。
编辑
main.tf
文件。在第 5 行中,插入一个拼写错误,使语法无效。 例如,将
var.location
替换为var.loaction
保存文件。
再次运行验证。
terraform validate
要点:
- 将出现一条错误消息,其中指示出错的代码行和错误说明。
如你所见,Terraform 在配置代码的语法中检测到一个问题。 此问题导致无法部署配置。
在将 Terraform 文件推送到版本控制系统之前,最好始终对这些文件运行 terraform validate
。 此外,应将此级别的验证添加到持续集成管道中。 在本文后面,我们将探讨如何配置 Azure 管道以自动验证。
3. 验证 Terraform 配置
在上一部分,你已了解如何验证 Terraform 配置。 此级别的测试特定于语法。 此测试没有考虑到 Azure 上可能已部署的内容。
Terraform 是一种声明性语言,这表示你将所需的内容声明为最终结果。 例如,假设资源组中有 10 个虚拟机。 你随后创建一个 Terraform 文件来定义 3 个虚拟机。 如果应用此计划,总数不会增加到 13。 相反,Terraform 会删除了其余的 7 个虚拟机,这样就只剩下 3 个。 运行 terraform plan
可确认应用执行计划的潜在结果,以避免意外。
若要生成 Terraform 执行计划,请运行 terraform plan。 此命令会连接到目标 Azure 订阅,以检查配置中已部署的部分。 然后,Terraform 将确定必要的更改以满足 Terraform 文件中所述的要求。 在此阶段,Terraform 不部署任何内容。 它会告诉你应用计划后将发生什么情况。
如果你正在按照本文进行操作,而且已完成上一部分中的步骤,请运行 terraform plan
命令:
terraform plan
运行 terraform plan
后,Terraform 将显示应用执行计划可能产生的结果。 输出指示将添加、更改和销毁的 Azure 资源。
默认情况下,Terraform 会将状态存储在 Terraform 文件所在的本地目录中。 此模式非常适合单用户方案。 但是,当多个用户处理同一 Azure 资源时,本地状态文件可能会不同步。为了解决此问题,Terraform 支持将状态文件写入远程数据存储(如Azure 存储)。 此情况下,在本地计算机上运行 terraform plan
并以远程计算机为目标可能会出现问题。 因此,在持续集成管道的过程中自动执行此验证步骤是有意义的。
4. 运行静态代码分析
可直接在 Terraform 配置代码上完成静态代码分析,无需执行它。 此分析可用于检测安全问题和符合性不一致等问题。
下列工具为 Terraform 文件提供静态分析:
静态分析通常作为持续集成管道的一部分执行。 这些测试不要求创建执行计划或部署。 因此,它们比其他测试运行速度更快,通常在持续集成过程中最先运行。
5. 使用 Azure 管道自动执行集成测试
持续集成包括在引入更改时测试整个系统。 在本部分中,你会看到一个用于实现持续集成的 Azure 管道配置。
使用所选的编辑器浏览到 GitHub 上的 Terraform 示例项目的本地克隆。
打开
samples/integration-testing/src/azure-pipeline.yaml
文件。向下滚动到“步骤”部分,这里有一组用于运行各种安装和验证例程的标准步骤。
查看显示“步骤 1:运行 Checkov 静态代码分析”的行。 在此步骤中,前面提到的
Checkov
项目将对示例 Terraform 配置运行静态代码分析。- bash: $(terraformWorkingDirectory)/checkov.sh $(terraformWorkingDirectory) displayName: Checkov Static Code Analysis
要点:
- 该脚本负责在装载到 Docker 容器内的 Terraform 工作区中运行 Checkov。 Microsoft 托管的代理已启用 Docker。 在 Docker 容器中运行工具更为简单,无需在 Azure 管道代理上安装 Checkov。
$(terraformWorkingDirectory)
变量是在azure-pipeline.yaml
文件中定义的。
查看显示“步骤 2:在 Azure Pipelines 代理上安装 Terraform”的行。 先前安装的“Terraform 构建和发布任务”扩展中有一个命令,它用于在运行 Azure 管道的代理上安装 Terraform。 此任务是在此步骤中执行的。
- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-installer.TerraformInstaller@0 displayName: 'Install Terraform' inputs: terraformVersion: $(terraformVersion)
要点:
- 要安装的 Terraform 版本通过名为
terraformVersion
的 Azure 管道变量进行指定,并在azure-pipeline.yaml
文件中定义。
- 要安装的 Terraform 版本通过名为
查看显示“步骤 3:运行 Terraform init 来初始化工作区”的行。 现已将 Terraform 安装在代理上,接下来可初始化 Terraform 目录。
- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0 displayName: 'Run terraform init' inputs: command: init workingDirectory: $(terraformWorkingDirectory)
要点:
command
输入指定了要运行的 Terraform 命令。workingDirectory
输入指示了 Terraform 目录的路径。$(terraformWorkingDirectory)
变量是在azure-pipeline.yaml
文件中定义的。
查看显示“步骤 4:运行 Terraform validate 来验证 HCL 语法”的行。 初始化项目目录后,运行
terraform validate
来验证服务器上的配置。- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0 displayName: 'Run terraform validate' inputs: command: validate workingDirectory: $(terraformWorkingDirectory)
查看显示“步骤 5:运行 Terraform plan 来验证 HCL 语法”的行。 如前所述,已生成执行计划来在部署之前验证 Terraform 配置是否有效。
- task: charleszipp.azure-pipelines-tasks-terraform.azure-pipelines-tasks-terraform-cli.TerraformCLI@0 displayName: 'Run terraform plan' inputs: command: plan workingDirectory: $(terraformWorkingDirectory) environmentServiceName: $(serviceConnection) commandOptions: -var location=$(azureLocation)
要点:
environmentServiceName
输入是指在配置环境中创建的 Azure 服务连接的名称。 Terraform 可通过该连接访问你的 Azure 订阅。commandOptions
输入用于将参数传递给 Terraform 命令。 在本例中,将指定一个位置。$(azureLocation)
变量之前已在 YAML 文件中进行定义。
将管道导入到 Azure DevOps
打开 Azure DevOps 项目并转到 Azure Pipelines 部分。
选择“创建管道”按钮。
对于“代码位置”选项,请选择“GitHub (YAML)”。
此时,你可能需要授权 Azure DevOps 来访问你的组织。 有关本主题的详细信息,请参阅构建 GitHub 存储库一文。
在存储库列表中,选择你在 GitHub 组织中创建的存储库的分支。
在“配置管道”步骤中,选择从现有的 YAML 管道开始。
显示“选择现有 YAML 管道”页面时,请指定分支
master
并输入 YAML 管道的路径:samples/integration-testing/src/azure-pipeline.yaml
。选择“继续”,从 GitHub 加载 Azure YAML 管道。
显示“查看管道 YAML”页面时,请选择“运行”来首次创建并手动触发管道。
验证结果
可通过 Azure DevOps UI 手动运行管道。 不过,本文的重点是介绍自动持续集成。 通过将更改提交到分叉存储库的 samples/integration-testing/src
文件夹来测试该过程。 此更改将在你推送代码的分支上自动触发新管道。
完成该步骤后,请查看 Azure DevOps 中的详细信息,确保一切正常运行。
Azure 上的 Terraform 故障排除
排查在 Azure 上使用 Terraform 时遇到的常见问题