ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Terratest 实战:为 Azure Container Instances(ACI)Terraform 模块编写自动化测试

Terratest 实战:为 Azure Container Instances(ACI)Terraform 模块编写自动化测试 测试开发工具DevOps质量保障【免费下载链接】terratestTerratest is a Go library that makes it easier to write automated tests for your infrastructure code.项目地址https://gitcode.com/gh_mirrors/te/terratest点击查看免费下载导读本文以 Terratest 仓库中的examples/azure/terraform-azure-aci-example示例模块为核心完整讲解如何用 Terraform 在 Azure 上部署一个 Azure Container Instance容器实例并借助 Terratest 编写 Go 自动化测试来验证部署结果。读完本文你将掌握该模块的 Terraform 配置结构、Azure 凭据与环境变量的配置方法、手动执行terraform apply的完整流程以及使用TestTerraformAzureACIExample这类端到端测试对真实云资源进行断言验证的完整实战方案。模块概览一个可测试的 ACI 部署单元该示例模块位于 examples/azure/terraform-azure-aci-example 目录是 Terratest 仓库中 Azure 示例族terraform-azure-*-example的一个成员。它的作用是通过 Terraform 在 Azure 中部署一个 Azure Container Instance下文简称 ACI用于演示如何为 Azure Terraform 代码编写自动化测试。模块文件结构如下文件作用main.tf声明 provider、资源组Resource Group与容器组Container Groupvariables.tf定义location与postfix两个输入变量output.tf导出资源组名、IP 地址、FQDN、容器实例名四个输出值README.md手动运行与自动化测试的操作说明与之配套的测试代码位于 test/azure/terraform_azure_aci_example_test.go断言所用的 Azure SDK 封装函数位于 modules/azure/containers.go。整体测试链路为Terraform 负责部署资源Terratest 的 Azure 模块负责独立核实资源真实属性与 Terraform 输出一致这正是 Terratest 对基础设施代码进行自动化验证的核心思想。手动运行该模块的完整步骤原文档给出了直接手动操作该模块的清单式步骤本文将其完整保留并补充关键细节注册 Azure 账号在 Azure 官网注册订阅用于创建资源组与容器实例。配置 Azure 凭据使用 Azure CLI 官方支持的方式完成认证配置服务主体、登录会话等任一受支持方式均可。安装 Terraform安装 Terraform 并将其加入系统PATH确保命令行可直接调用terraform。准备环境变量确保ARM_CLIENT_ID、ARM_CLIENT_SECRET、ARM_SUBSCRIPTION_ID、ARM_TENANT_ID等环境变量已在测试主机上就绪详见下文环境变量与 Azure 凭据配置一节。初始化在模块目录下运行terraform init下载hashicorp/azurermprovider。应用部署运行terraform apply创建资源组与容器组。清理资源操作完成后运行terraform destroy销毁本次部署的全部资源。注意手动运行后必须执行terraform destroy避免资源长期留存产生不必要的 Azure 账单。Terraform 配置逐项解析provider 与版本约束main.tf模块在 main.tf 中声明了 Terraform 与 provider 的版本约束terraform { required_version 1.0 required_providers { azurerm { source hashicorp/azurerm version ~ 3.0 } } } provider azurerm { features {} }required_version 1.0要求 Terraform 1.0 及以上版本azurerm ~ 3.0锁定 AzureRM provider 的 3.x 系列允许 3.0 到 4.0 之前的次版本更新features {}开启 azurerm provider 的可选功能块是 AzureRM 3.x 使用时的常规配置。资源组与容器组main.tf模块部署两个核心资源resource azurerm_resource_group rg { name terratest-aci-rg-${var.postfix} location var.location } resource azurerm_container_group aci { name aci${var.postfix} location azurerm_resource_group.rg.location resource_group_name azurerm_resource_group.rg.name ip_address_type Public dns_name_label aci${var.postfix} os_type Linux container { name hello-world image mcr.microsoft.com/azuredocs/aci-helloworld:latest cpu 0.5 memory 1.5 ports { port 443 protocol TCP } } tags { Environment Development } }关键配置点说明资源组命名terratest-aci-rg-${var.postfix}通过postfix变量规避不同测试执行之间的资源名冲突详见下文变量说明IP 地址类型ip_address_type Public使容器组获得公网 IP并配合dns_name_label生成可访问的 FQDN容器镜像使用微软官方示例镜像mcr.microsoft.com/azuredocs/aci-helloworld:latest这是一个内置 Web 服务的最小演示镜像资源配置cpu 0.5、memory 1.5单位 GiB属于 ACI 支持的小规格组合适合免费额度范围内的演示端口映射暴露 TCP 443 端口标签打上Environment Development便于在 Azure 门户中识别资源用途。输入变量variables.tfvariables.tf 定义了模块仅有的两个可选变量均带合理默认值variable location { description The supported azure location where the resource exists type string default West US2 } variable postfix { description A postfix string to centrally mitigate resource name collisions. type string default 1276 }location资源部署的 Azure 区域默认West US2可按需改为其他受支持的区域postfix附加在资源名后的随机后缀字符串默认1276用于集中缓解资源命名冲突——这是云资源自动化测试中的常见手段因为 Azure 资源名尤其是公网 FQDN具有全局唯一性要求多次执行部署时必须避免重名。输出变量output.tfoutput.tf 导出四个输出值它们同时是自动化测试的断言目标output resource_group_name { value azurerm_resource_group.rg.name } output ip_address { value azurerm_container_group.aci.ip_address } output fqdn { value azurerm_container_group.aci.fqdn } output container_instance_name { value azurerm_container_group.aci.name }这四个输出分别对应资源组名称、容器组的公网 IP、FQDN由dns_name_label生成与容器实例名称。测试正是通过terraform output读取这些值再与 Azure SDK 返回的真实状态做比对。环境变量与 Azure 凭据配置Terratest 的 Azure 测试链路中Terraform 与 Azure SDK 均需要凭据支持。仓库的 examples/azure/README.md 对此有完整说明需要设置四个核心环境变量并在非公有云场景下设置AZURE_ENVIRONMENTexport ARM_CLIENT_IDyour_app_id export ARM_CLIENT_SECRETyour_password export ARM_SUBSCRIPTION_IDyour_subscription_id export ARM_TENANT_IDyour_tenant_id # AZURE_ENVIRONMENT 取值之一不设置时默认 AzurePublicCloud export AZURE_ENVIRONMENTAzureUSGovernmentCloud export AZURE_ENVIRONMENTAzureChinaCloud export AZURE_ENVIRONMENTAzureGermanCloud export AZURE_ENVIRONMENTAzurePublicCloud export AZURE_ENVIRONMENTAzureStackCloud在 Windows 环境下这些变量应设置为系统环境变量可使用管理员权限的 PowerShell 控制台完成例如[System.Environment]::SetEnvironmentVariable(ARM_CLIENT_ID,$your_app_id,[System.EnvironmentTarget]::Machine) [System.Environment]::SetEnvironmentVariable(ARM_CLIENT_SECRET,$your_password,[System.EnvironmentTarget]::Machine) [System.Environment]::SetEnvironmentVariable(ARM_SUBSCRIPTION_ID,$your_subscription_id,[System.EnvironmentTarget]::Machine) [System.Environment]::SetEnvironmentVariable(ARM_TENANT_ID,$your_tenant_id,[System.EnvironmentTarget]::Machine) [System.Environment]::SetEnvironmentVariable(AZURE_ENVIRONMENT,$your_azure_env,[System.EnvironmentTarget]::Machine)从源码看AZURE_ENVIRONMENT由 modules/azure/client_factory.go 中的AzureEnvironmentEnvName常量读取getDefaultEnvironmentName()在未设置该变量时默认返回AzurePublicCloud环境名会进一步影响 Azure SDK 客户端的云端点选择例如 GetStorageURISuffixContextE 会根据环境返回不同的存储服务后缀。此外Terratest 的 Azure 模块还支持两个可选环境变量见 modules/azure/common.goARM_SUBSCRIPTION_ID测试调用 Azure SDK 时未显式传入订阅 ID 时从此环境变量读取AZURE_RES_GROUP_NAME同理用于指定目标资源组名称。这使得测试代码可以省略订阅 ID / 资源组参数直接从环境变量解析目标。运行自动化测试从命令到断言执行测试的命令原文档给出的自动化测试运行步骤如下注册 Azure 账号并配置凭据同上安装 Terraform 并加入PATH配置 Terratest 的 Go 测试环境参见 examples/azure/README.md需安装 Go 并保证仓库已正确检出进入测试目录cd test/azure编译验证go build terraform_azure_aci_example_test.go运行测试go test -v -timeout 60m -tags azure -run TestTerraformAzureACIExample。其中两个关键参数含义如下-tags azure测试文件首行为//go:build azure见 terraform_azure_aci_example_test.go只有带上该构建标签才会把测试编译进二进制避免默认go test ./...误触发需要云凭据的用例-timeout 60m因测试需要真实的terraform init、terraform apply与资源销毁整个过程可能长达数分钟需设置充裕的超时时间。测试代码逐段解读完整的测试实现位于 test/azure/terraform_azure_aci_example_test.go核心流程如下第一步构造 Terraform 选项uniquePostfix : strings.ToLower(random.UniqueID()) terraformOptions : terraform.Options{ TerraformDir: ../../examples/azure/terraform-azure-aci-example, Vars: map[string]interface{}{ postfix: uniquePostfix, }, }使用random.UniqueID()来自 modules/core/v2/random生成随机后缀并转为小写作为postfix变量注入保证每次测试执行的资源名互不冲突TerraformDir指向示例模块目录。第二步延迟销毁defer terraform.DestroyContext(t, t.Context(), terraformOptions)defer保证无论测试成功与否函数返回前都会执行terraform destroy清理本次创建的所有资源。这也是 modules/terraform/apply.go 中InitAndApplyContext的设计约定——该方法不会调用 destroy清理责任由调用方承担因此测试必须显式 defer 销毁。第三步初始化并应用terraform.InitAndApplyContext(t, t.Context(), terraformOptions)InitAndApplyContext内部依次执行terraform init与terraform apply -inputfalse -auto-approve见 modules/terraform/apply.go 与ApplyContextE中的参数构造 modules/terraform/apply.go任一步出错都会通过require.NoError直接让测试失败。第四步读取输出值resourceGroupName : terraform.OutputContext(t, t.Context(), terraformOptions, resource_group_name) aciName : terraform.OutputContext(t, t.Context(), terraformOptions, container_instance_name) ipAddress : terraform.OutputContext(t, t.Context(), terraformOptions, ip_address) fqdn : terraform.OutputContext(t, t.Context(), terraformOptions, fqdn)通过terraform output读取 output.tf 中声明的四个输出值。第五步断言真实资源状态assert.True(t, azure.ContainerInstanceExistsContext(t, t.Context(), aciName, resourceGroupName, )) actualInstance : azure.GetContainerInstanceContext(t, t.Context(), aciName, resourceGroupName, ) assert.Equal(t, ipAddress, *actualInstance.Properties.IPAddress.IP) assert.Equal(t, fqdn, *actualInstance.Properties.IPAddress.Fqdn)ContainerInstanceExistsContext确认容器实例确实存在于 Azure 上GetContainerInstanceContext获取容器组的完整对象从中取出Properties.IPAddress.IP与Properties.IPAddress.Fqdn与 Terraform 输出的ip_address、fqdn逐一比对。底层 Azure SDK 封装原理上述断言函数并非凭空存在它们由 modules/azure/containers.go 实现。核心链路如下ContainerInstanceExistsContext→ContainerInstanceExistsContextE调用GetContainerInstanceContextE若返回ResourceNotFoundErrorExists(err)则判定为不存在返回false, nil其他错误则原样返回modules/azure/containers.goGetContainerInstanceContext→GetContainerInstanceContextE先通过getTargetAzureResourceGroupName解析资源组名为空时读取AZURE_RES_GROUP_NAME环境变量再调用CreateContainerInstanceClientContextE创建 SDK 客户端最终调用client.Get(ctx, rgName, instanceName, nil)向 Azure ARM API 发起查询modules/azure/containers.goSDK 客户端的创建位于 modules/azure/client_factory.gogetArmContainerInstanceClientFactory使用armcontainerinstance.NewClientFactory构建工厂内部基于AZURE_ENVIRONMENT配置云端点、基于订阅 ID 与默认凭据azidentity.NewDefaultAzureCredential完成认证。也就是说测试对资源的核实不依赖 Terraform 自身的状态文件而是通过 Azure SDK 直接查询云上资源的真实属性后再做比对——这正是 examples/azure/README.md 所描述的 Terratest Azure 测试模式使用 azure-sdk-for-go 独立确认实际 Azure 资源属性与 Terraform 输出变量给出的期望状态一致。此外modules/azure/containers_test.go 中的TestGetContainerInstanceWithClient通过 azure-sdk-for-go 的 fake transport 验证了该查询逻辑的成功与 NotFound 两种分支可在无真实云环境下对封装函数做单元验证。成本提示与注意事项原文档特别强调该模块及其自动化测试会在你的 Azure 账户中部署真实资源可能产生费用。不过本次示例所用资源资源组 单容器组规格 0.5 核 / 1.5 GiB均属于 Azure 免费账户 覆盖范围若免费额度尚未用完一般可免费运行但用户需对全部 Azure 费用自行负责。因此建议测试前确认订阅与预算避免在非预期订阅中运行依赖测试中的defer terraform.DestroyContext自动清理手动部署则务必在结束后执行terraform destroy若已用完免费额度可先估算 ACI 按秒计费的成本再决定是否运行。延伸阅读仓库级 Azure 测试环境配置总览examples/azure/README.md同一测试目录下的其他 Azure 示例测试test/azureAzure 模块的全部 SDK 封装modules/azureTerraform 模块的封装实现modules/terraform总结通过本文你可以完整复现 Terratest 对 Azure Container Instance 的自动化测试闭环Terraform 模块负责可复现的部署main.tf 定义资源、variables.tf 通过postfix规避命名冲突、output.tf 暴露断言目标而 terraform_azure_aci_example_test.go 则借助 modules/azure 的 SDK 封装将Terraform 声称的状态与Azure 上的真实状态进行独立比对。这套模式可以直接迁移到 AKS、Cosmos DB、Key Vault 等仓库中其他 Azure 示例模块是验证基础设施代码正确性的通用范式。赞分享测试开发工具DevOps质量保障【免费下载链接】terratestTerratest is a Go library that makes it easier to write automated tests for your infrastructure code.项目地址https://gitcode.com/gh_mirrors/te/terratest点击查看免费下载相关推荐在 Codex 中通过 Rube MCP 自动化 Ritekit 运营任务Ritekit Automation 技能实战指南在 Codex 中通过 Rube MCP 自动化 Ritekit 运营任务Ritekit Automation 技能实战指南 本篇技术指南围绕本仓库中的 ri测试开发工具DevOps质量保障escrcpy 远程设备隧道连接完全指南远程 ADB 服务器与 SSH 隧道实战escrcpy 远程设备隧道连接完全指南远程 ADB 服务器与 SSH 隧道实战 本指南基于 escrcpy 仓库中的 tunnels.md https://测试开发工具DevOps质量保障Owncast 产品定义深度解读为 DIY 主播与集成者打造的自托管直播平台Owncast 产品定义深度解读为 DIY 主播与集成者打造的自托管直播平台 Owncast 是一个开源的、自托管的、去中心化的单用户直播与聊天服务器。其 产测试开发工具DevOps质量保障上一篇Momentum-Firmware WiFi优化最简单设置流程解析下一篇torchtune模型并行路线图2025年技术愿景创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表