Terraform部署Azure存储容器报403授权失败问题排查
Terraform部署Azure存储容器返回403授权失败问题排查
问题现象
- 首次部署Azure存储容器时,因尚未启用IP过滤策略可正常执行,后续所有部署均失败
- 执行
terraform plan命令时返回如下403错误:
Error: retrieving Container "xxxx" (Account "xxxx" / Resource Group "xxx"): containers.Client#GetProperties: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationFailure" Message="This request is not authorized to perform this operation.\nRequestId:62a85c92-901e-0021-12de-816608000000\nTime:2022-06-17T00:11:56.2063816Z"
- 已尝试的修复操作均未生效:
- 在流水线中通过Azure CLI任务调用
curl -s https://api.ipify.org/获取当前代理公网IP,添加为存储账户防火墙白名单规则 - 添加规则后设置300秒等待时长,确认规则已成功写入白名单,且白名单配置与
terraform plan执行处于同一流水线阶段 - 补充将DevOps组织所在区域的114个IP段全部加入白名单,问题仍然存在
- 排查发现获取到的流水线代理IP,不在命令
az network list-service-tags --location australiaeast --query "values[?name == 'AzureCloud.australiaeast'].properties.addressPrefixes[]"返回的IP段范围内
- 在流水线中通过Azure CLI任务调用
- 现有流水线白名单配置片段:
- task: AzureCLI@2 inputs: azureSubscription: '$(azureSubscription)' scriptType: 'bash' scriptLocation: 'inlineScript' inlineScript: | agentIP=$(curl -s https://api.ipify.org/) az storage account network-rule add -g xxx --account-name xxx --ip-address $agentIP sleep 300
根因分析
- 核心问题是网络路径判断错误:你添加的托管代理公网出口IP,根本不是Terraform调用存储账户API的源IP。Terraform通过Azure服务主体认证调用存储管理接口时,走的是Azure Resource Manager(ARM)内部服务转发路径,源IP归属ARM服务集群,不是你从公网API查到的DevOps托管代理出口IP,加再多代理相关的IP段都没用。
- 服务标签匹配错误:你之前查询的
AzureCloud.australiaeast是区域内Azure公有云通用资源IP段,ARM跨服务调用对应的服务标签是AzureResourceManager,按区域拆分的标签为AzureResourceManager.australiaeast,加错标签范围自然无法覆盖调用源。 - 你发现代理IP不在AzureCloud段内是正常现象:Microsoft托管代理的公网出口归属
AzureDevOps专属服务标签,不属于通用AzureCloud地址范围,但这个IP本身就不需要加入存储白名单。 - 存储账户网络规则生效时间通常不超过30秒,设置300秒等待完全没有必要,等待后仍报错就可以直接判定是规则加错了源,不是生效延迟问题。
解决方案
按优先级从高到低选择即可:
- 推荐方案(零额外IP维护成本):在存储账户网络规则中开启受信任服务旁路权限,允许受信任列表内的Azure服务访问存储账户。Terraform使用的服务主体/托管身份属于默认受信任范畴,开启后无需配置任何公网IP白名单即可正常调用。可以直接在Terraform的存储账户资源块中配置该规则:
resource "azurerm_storage_account" "example" { # 省略其余原有存储配置参数 network_rules { default_action = "Deny" # 允许Blob等存储服务访问,按需调整 allowed_services = ["Blob", "File", "Table", "Queue"] # 开启受信任Azure服务旁路 bypass = ["AzureServices"] # 保留你原有需要的IP规则、VNet规则 ip_rules = [] virtual_network_subnet_ids = [] } }
首次部署完成该配置后,后续所有Terraform操作都不会再被存储防火墙拦截。
2. 若合规要求不允许开启受信任服务旁路,则不要添加代理公网IP,而是将存储账户所在区域对应的AzureResourceManager服务标签全量IP段加入存储账户IP规则,例如澳大利亚东部区域就添加AzureResourceManager.australiaeast对应的地址前缀列表。
3. 高安全场景可选方案:为存储账户配置私有终结点,使用接入同VNet的自托管DevOps代理执行Terraform部署,通过内网路径访问存储账户,完全绕开公网防火墙限制,该方案运维成本较高,按需选择。
- 连通性验证技巧:后续调整网络规则后,不需要靠固定sleep等待生效,直接在同一执行上下文运行
az storage container list --account-name <你的存储名> --auth-mode login测试连通性,命令返回正常再执行后续Terraform步骤即可。
内容的提问来源于stack exchange,提问作者HLT
相关产品推荐
相关产品推荐

