OpenTofu Azure 远端状态后端验收测试指南:环境准备、鉴权方式与测试运行全解析
发布时间:2026/9/19 13:11:13 作者:尧图编辑部 阅读量:1,286

OpenTofu Azure 远端状态后端验收测试指南环境准备、鉴权方式与测试运行全解析【免费下载链接】opentofuOpenTofu lets you declaratively manage your cloud infrastructure.项目地址: https://gitcode.com/gh_mirrors/op/opentofuOpenTofu 的 Azure 远端状态后端backend azurerm将terraform.tfstate存放在 Azure Blob Storage 中并通过存储账户的访问密钥Access Key、SAS Token、服务主体Client Secret / Client Certificate、托管身份MSI、AKS Workload Identity 与 Azure DevOps 服务连接等多种鉴权方式访问状态文件。本文以仓库中 internal/backend/remote-state/azure/README.md 为骨架结合该目录下的源码与测试实现完整讲解如何在真实 Azure 订阅上搭建测试基础设施、配置全部环境变量、运行单元测试与各类验收测试Acceptance Tests并深入剖析后端配置的底层鉴权选择逻辑。一、测试体系概览单元测试与验收测试Azure 后端的状态管理与客户端实现测试集中在两个文件backend_test.go验证后端Backend的配置解析、状态管理、锁与强制解锁等能力client_test.go验证远端状态客户端RemoteClient的读写、元数据维护、锁等能力。这两个文件同时包含单元测试与验收测试两类用例判别标准只有一个凡测试函数名以TestAcc...开头即为验收测试其余皆为单元测试。单元测试不需要任何 Azure 环境即可运行例如TestBackend_impl仅断言*Backend实现了backend.Backend接口见 backend_test.goTestBackendConfig与TestBackendConfig_Timeout仅实例化客户端、解析配置不发起任何真实请求、不产生费用见 backend_test.goTestBackendPagination使用 mock 客户端模拟 10,000 个 blob 的分页遍历验证getPaginatedResults的分页聚合逻辑见 backend_test.goTestStorageNames验证checkAccountAndContainerNames对存储账户名与容器名的命名规则校验见 backend_test.go。验收测试默认被跳过。跳过判定逻辑位于 helpers_test.goskip : os.Getenv(TF_ACC) os.Getenv(TF_AZURE_TEST) 即只有同时满足TF_ACC或TF_AZURE_TEST任一非空验收测试才会真正执行。注意所有测试均假定运行在Azure 公共云Azure Public Cloud上未针对 Azure 中国区、Azure Government 或 Azure Stack 等特殊环境适配在这些环境中运行会失败。二、环境准备基础环境变量与 Azure CLI 鉴权运行任何验收测试之前需要先导出如下环境变量export TF_AZURE_TEST1 export TF_ACC1此外还必须提供 Azure 区域location、订阅 ID 与租户 IDexport ARM_LOCATIONcentralus export ARM_SUBSCRIPTION_IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx export ARM_TENANT_IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx从源码角度看ARM_SUBSCRIPTION_ID与ARM_TENANT_ID同时也是后端配置项subscription_id、tenant_id的环境变量默认值来源见 backend.goARM_LOCATION则被测试的辅助函数testResourceNames读取用于创建资源组与存储账户见 helpers_test.go。基础设施引导阶段创建资源组、存储账户与 Blob 容器建议使用Azure CLIaz完成登录鉴权az login如果无法使用 Azure CLI也可以通过设置TF_AZURE_TEST_CLIENT_ID与TF_AZURE_TEST_CLIENT_SECRET以服务主体方式运行测试。配置完成后即可运行以下 4 个基础的验收测试TestAccBackendAccessKeyBasicTestAccBackendSASTokenTestAccRemoteClientAccessKeyBasicTestAccRemoteClientSASToken源码视角测试如何引导基础设施以TestAccBackendAccessKeyBasic为例见 backend_test.go其执行流程为调用testAccAzureBackend(t)检查验收测试开关用acctest.RandString(4)生成随机后缀构造资源命名如acctestRG-backend-时间戳-随机串、acctestsa随机串通过auth.GetAuthMethodConstruct获得 Token 凭证调用createTestResources创建资源组、StorageV2 存储账户StandardLRS与 Blob 容器并把存储账户访问密钥回写到res.storageAccountAccessKey用t.Cleanup注册destroyTestResources无论测试成败都会删除资源组完成清理见 helpers_test.go。SAS Token 测试则由getSASToken基于共享密钥生成有效期从前 5 分钟至未来 24 小时权限覆盖读、写、删除、列举、追加、创建、更新、处理资源类型为sco服务、容器、对象强制 HTTPS见 helpers_test.go。三、用 meta-test 工作空间搭建测试基础设施目录 meta-test 中的 OpenTofu 工作空间可为验收测试创建所需的应用注册、证书、VM、AKS 集群等基础设施使用前提是你在 Azure 订阅中具备管理员权限。详细说明见 meta-test/README.md。首先使用 CLI 登录并指定订阅$ az login $ export ARM_SUBSCRIPTION_IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx随后初始化并应用工作空间$ tofu init $ tofu apply # 需要以明文输出敏感变量时 $ tofu apply -show-sensitive应用完成后会输出类似如下的环境变量将其复制到命令行即可供测试使用export TF_AZURE_TEST_CLIENT_IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx export TF_AZURE_TEST_CLIENT_SECRETsome~secret~string同时工作空间还会生成certs.pfx文件用于证书鉴权测试export TF_AZURE_TEST_CERT_PATHmeta-test/certs.pfx export TF_AZURE_TEST_CERT_PASSWORDSoMePaSsWoRdMSI、AKS Workload Identity、CMK 等重基础设施默认不创建通过变量按需开启变量定义见 meta-test/variables.tf# 创建 MSI 测试所需的 VM、托管身份与授权 $ tofu apply -show-sensitive -var use_msitrue -var locationcentralus -var ssh_pub_key_path~/.ssh/id_rsa.pub # 创建 AKS Workload Identity 测试所需的集群与授权 $ tofu apply -show-sensitive -var use_aks_workload_identitytrue -var locationcentralus # 创建 CMK客户托管密钥测试所需的 Key Vault、加密密钥与加密作用域 $ tofu apply -show-sensitive -var use_cmktrue -var locationcentraluslocation与ssh_pub_key_path均有默认值centralus与~/.ssh/id_rsa.pub可省略拆除某类重基础设施而保留其余凭据时只需不带对应变量重新执行tofu apply彻底清理所有测试基础设施$ tofu destroy四、按鉴权方式运行各类验收测试除前文 4 个基础测试外其余验收测试均要求以服务主体或客户端凭据完成鉴权。meta-test 工作空间会自动创建应用注册并托管凭据若需手动创建可在 Azure 门户中新建应用注册并在其证书和机密Certificates secrets部分维护客户端机密与证书。4.1 Client Secret客户端机密测试需要额外设置export TF_AZURE_TEST_CLIENT_IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx export TF_AZURE_TEST_CLIENT_SECRETsome~secret~string配置完成后可运行TestAccBackendServicePrincipalClientSecretTestAccRemoteClientServicePrincipalClientSecret从源码可见这两个测试在缺少TF_AZURE_TEST_CLIENT_ID或TF_AZURE_TEST_CLIENT_SECRET时会跳过并提示请手动设置或使用 meta-test 目录中的 terraform plan而ARM_TENANT_ID缺失时则直接报错见 backend_test.go。测试通过client_id、client_secret、use_clifalse等配置构造后端并借助TestBackendStateForceUnlock与TestBackendStateLocksInWS验证多工作空间的锁行为。4.2 Client Certificate客户端证书测试需要额外设置export TF_AZURE_TEST_CLIENT_IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx export TF_AZURE_TEST_CERT_PATHmeta-test/certs.pfx export TF_AZURE_TEST_CERT_PASSWORDsOmEpAsSwOrD如果应用了 meta-test 工作空间证书会自动生成并挂载到权限合适的应用上。否则可用openssl手动生成# 生成密钥对 证书 ~ openssl req -subj /CNmyclientcertificate/OMyCompany, Inc./STCA/CUS \ -new -newkey rsa:4096 -sha256 -days 3 -nodes -x509 -keyout client.key -out client.crt # 生成状态后端要求的 PFX 包使用 PBE-SHA1-3DES 与 sha1 MAC 算法 ~ openssl pkcs12 -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -export -macalg sha1 -password pass: -out client.pfx -inkey client.key -in client.crt随后进入 Azure 门户手动将公开的client.crt文件上传到应用注册的证书中。对应验收测试为TestAccBackendServicePrincipalClientCertificate。源码中该测试在TF_AZURE_TEST_CLIENT_ID或TF_AZURE_TEST_CERT_PATH缺失时跳过并会先读取验证证书文件内容见 backend_test.go。注意TF_AZURE_TEST_CERT_PASSWORD可以为空测试以client_certificate_path与client_certificate_password两个配置项传入后端。4.3 Managed Service IdentityMSI测试强烈建议使用 meta-test 工作空间搭建 VM 与相关授权。搭建完成后在 README 同级目录编译测试二进制$ GOOSlinux GOARCHamd64 go test -c .生成azure.test文件后传送到 VM$ scp azure.test azureadminxxx.xxx.xxx.xxx:/home/azureadminSSH 登录 VM$ ssh azureadminxxx.xxx.xxx.xxx在 VM 内配置环境变量export TF_AZURE_TEST1 export TF_ACC1 export ARM_LOCATIONcentralus export ARM_SUBSCRIPTION_IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx export ARM_TENANT_IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx export TF_AZURE_TEST_STORAGE_ACCOUNT_NAMEacctestsaxxxx export TF_AZURE_TEST_RESOURCE_GROUP_NAMEacctestRG-backend-1234567890-xxxx export TF_AZURE_TEST_CONTAINER_NAMEacctestcont最后运行 MSI 测试$ ./azure.test -test.v -test.run TestAcc.*ManagedServiceIdentity源码揭示了 MSI 测试的特殊之处TestAccBackendManagedServiceIdentity不会自行创建资源组、存储账户或容器而是要求全部通过上述三个TF_AZURE_TEST_*环境变量预先提供缺失时测试直接跳过见 backend_test.go。测试以后端配置use_msitrue构造用azidentity.NewManagedIdentityCredential获取凭证并在结束后手动清理容器内 blob。4.4 AKS Workload Identity 测试同样强烈建议使用 meta-test 工作空间搭建 AKS 集群与授权。在 README 同级目录编译$ GOOSlinux GOARCHamd64 go test -c .假设kubectl已配置为可访问default命名空间下名为shell-demo的 Pod将测试二进制复制进去kubectl cp azure.test shell-demo:/进入 Podkubectl exec --stdin --tty shell-demo -- /bin/sh在 Pod 内配置环境变量export TF_AZURE_TEST1 export TF_ACC1 export ARM_LOCATIONcentralus export ARM_SUBSCRIPTION_IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx export ARM_TENANT_IDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx export TF_AZURE_TEST_STORAGE_ACCOUNT_NAMEacctestsaxxxx export TF_AZURE_TEST_RESOURCE_GROUP_NAMEacctestRG-backend-1234567890-xxxx export TF_AZURE_TEST_CONTAINER_NAMEacctestcont运行 AKS Workload Identity 测试$ ./azure.test -test.v -test.run TestAcc.*AKSWorkloadIdentitymeta-test 工作空间会在aks_kubectl_instructions输出中给出获取集群凭据、创建带azure.workload.identity/use: true标签的 ServiceAccount 与 Pod 的完整 YAML详见 meta-test/README.mdshell-demoPod 即测试运行的工作负载。对应的源码实现TestAccBackendAKSWorkloadIdentity使用use_aks_workload_identitytrue配置后端并以azidentity.NewWorkloadIdentityCredential获取凭证见 backend_test.go。4.5 Azure DevOpsADO Workload Identity测试该测试验证后端在 Azure DevOps Pipeline 中通过服务连接 OIDC 联邦身份鉴权的能力。前置条件一个 Microsoft Entra 租户及 Azure 订阅、在租户中创建 Azure DevOps 组织的权限、创建服务连接的权限以及至少Cloud Application Administrator角色来创建测试所需的应用注册。准备步骤访问 https://aex.dev.azure.com/ 并使用 Microsoft Entra 账号登录新建一个专用于测试的 Azure DevOps 组织若组织创建方式未自动关联目录进入Organization Settings - Microsoft Entra使用Connect Directory将 ADO 关联到你的 Entra 租户为你的账号创建/添加 SSH 密钥为 ADO 组织申请 Pipeline Parallelism审核可能需数天也可在Organization Settings - Billing中关联 Azure 订阅后付费购买并行度——测试完成后务必关闭该计费项否则即使闲置也会持续扣费在meta-test目录设置测试所需的变量将use_ado设为true以启用 Azure DevOps 相关测试见 meta-test/variables.tf导出环境变量AZDO_ORG_SERVICE_URL值为 ADO 组织 URL如https://dev.azure.com/myorg在meta-test目录运行tofu apply配置 ADO 组织并创建测试所需的服务连接按tofu apply输出的后续指引继续操作。完成上述准备后使用 ADO 服务连接的 Azure 后端测试即可正常运行。对应的TestAccBackendADOWorkloadIdentity见 backend_test.go读取AZURESUBSCRIPTION_SERVICE_CONNECTION_ID、ARM_TENANT_ID、ARM_CLIENT_ID、SYSTEM_OIDCREQUESTURI、SYSTEM_ACCESSTOKEN等环境变量这些正是 ADO Pipeline 中自动注入的变量以后端配置use_azuread_authtrue、use_oidctrue、ado_service_connection_id...构造并通过azidentity.NewAzurePipelinesCredential获取凭证。五、源码级原理后端鉴权方式的选择顺序理解了所有测试的鉴权路径后可以顺带理清后端在真实运行时的鉴权决策链这对理解测试为何要覆盖如此多组合至关重要。在 backend.go 的configure中鉴权按以下优先级依次判断Access Key若配置了access_key环境变量ARM_ACCESS_KEY直接以存储账户访问密钥构造容器客户端SAS Token否则若配置了sas_token环境变量ARM_SAS_TOKEN以 SAS Token 构造容器客户端Azure ADEntra ID认证若配置了use_azuread_auth直接用所选认证方法得到的 Token 凭证构造客户端兜底路径使用所选认证方法获取凭证后进一步调用AugmentConfig补全资源组与订阅信息再换取存储账户共享密钥来构造客户端。第 3、4 步所依赖的所选认证方法由auth.GetAuthMethod决定。在 auth/auth.go 中认证方法按如下顺序逐一执行Validate第一个校验通过者被选中Client CertificateclientCertAuthClient SecretclientSecretCredentialAuthAzure DevOps / PipelinesadoAuth注释明确指出它必须先于通用 OIDC因为它是更特化的 OIDC 认证通用 OIDCoidcAuth支持 GitHub Actions、ACTIONS_ID_TOKEN_REQUEST_URL等Managed IdentitymanagedIdentityAuthWorkload IdentityworkloadIdentityAuthAzure CLIazureCLICredentialAuth全部校验失败时返回错误No valid azure auth methods found。这与 meta-test 工作空间依次覆盖 client secret、client cert、MSI、AKS Workload Identity、ADO 各类场景一一对应也解释了为什么 README 要求按鉴权方式分组配置环境变量。此外无论采用哪种鉴权configure都会先调用checkAccountAndContainerNames校验命名见 backend.go存储账户名须为 3–24 位小写字母与数字容器名须为 3–63 位小写字母、数字与连字符且不得以连字符开头/结尾、不得出现连续连字符——这也是TestStorageNames单元测试逐条验证的规则。六、针对完整 tofu 二进制的测试技巧有些场景需要针对完整的tofu二进制做端到端验证例如历史上 issue #3586 所遇到的情况。在 opentofu 仓库根目录执行$ GOOSlinux GOARCHamd64 make build将产出的二进制scp到服务器后即可在服务器上运行./tofu init、./tofu apply等命令验证 azurerm 后端在真实二进制下的表现。七、测试运行要点小结单元测试无需任何配置即可运行go test或go test ./internal/backend/remote-state/azure/...均可。验收测试开关TF_AZURE_TEST1与TF_ACC1二者设其一即生效对应 helpers_test.go 的跳过逻辑。公共云限定测试仅面向 Azure Public Cloud在 Azure China / Government / Stack 中会失败。基础设施引导优先使用 Azure CLI 鉴权meta-test工作空间main.tf可一键创建应用注册、证书、VM、AKS 集群与 CMK 资源并以tofu apply -show-sensitive输出全部测试所需环境变量。命名规则TF_AZURE_TEST_CLIENT_ID/TF_AZURE_TEST_CLIENT_SECRET刻意采用不同于默认ARM_CLIENT_ID/ARM_CLIENT_SECRET的命名避免与后端默认客户端凭据冲突、遮蔽特定鉴权方式的测试见 helpers_test.go 注释。测试清理除 MSI / AKS / ADO 这类复用预置基础设施的测试外其余测试均通过t.Cleanup自动删除所创建的资源组meta-test 基础设施则通过tofu destroy统一清理。通过本文的变量清单、命令序列与源码佐证你可以从零开始在一个 Azure 订阅上完成 azurerm 后端全部六类鉴权方式的验收测试并在排查问题时快速定位到对应的配置项与底层实现文件。【免费下载链接】opentofuOpenTofu lets you declaratively manage your cloud infrastructure.项目地址: https://gitcode.com/gh_mirrors/op/opentofu创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考