Ansible下载Azure Blob遇认证失败,求解决方案
问题场景
需要将Azure Blob中的RDS证书下载到Windows目标机器,计划先下载到Ansible控制节点再通过copy模块传输。已满足前置条件:Python 3.12.3、azcollection 2.7.0,编写了对应的Role和Playbook,且服务主体已分配Contributor和Storage Blob Data Contributor RBAC角色,但执行时始终报AuthorizationFailure错误。
用到的Role代码
- name: Download RDS Certificate azure.azcollection.azure_rm_storageblob: resource_group: "{{ resource_group }}" storage_account_name: "{{ storage_account }}" container: "{{ storage_container }}" blob: "{{ cert_blob }}" dest: "/tmp/{{ cert_blob }}" auth_source: auto subscription_id: "{{ lookup('env', 'AZURE_SUBSCRIPTION_ID') }}" client_id: "{{ lookup('env', 'AZURE_CLIENT_ID') }}" secret: "{{ lookup('env', 'AZURE_SECRET') }}" tenant: "{{ lookup('env', 'AZURE_TENANT') }}" register: rds_certificate_downloaded until: rds_certificate_downloaded is succeeded retries: 2 delay: 10 ignore_errors: true #temporarily added
Playbook代码
- name: Perform activities pertaining to other RDS activities hosts: "localhost" connection: local roles: - plt_engg/download-rds-certificate tags: - download-rds-certificate
错误信息核心内容
azure.core.exceptions.HttpResponseError: This request is not authorized to perform this operation. RequestId:c5b434b1-d01e-0075-6380-2fa3b3000000 Time:2024-11-05T12:41:47.2537019Z ErrorCode:AuthorizationFailure
解决步骤
1. 验证RBAC角色的有效性与作用范围
- 检查角色分配层级:确保
Storage Blob Data Contributor角色是直接分配到目标存储账户上,而非仅分配到资源组或订阅级(如果订阅级有排除规则,可能导致权限不生效)。 - 等待RBAC生效:Azure RBAC角色分配后可能有1-15分钟的延迟,刚添加的角色不要立即测试。
- 用AZ CLI测试权限:直接用服务主体登录并尝试下载Blob,验证权限是否真的生效:
如果此命令也报错,说明RBAC配置确实有问题;如果成功,则问题出在Ansible模块的认证配置上。# 登录服务主体 az login --service-principal -u $AZURE_CLIENT_ID -p $AZURE_SECRET --tenant $AZURE_TENANT # 切换到目标订阅 az account set --subscription $AZURE_SUBSCRIPTION_ID # 尝试下载Blob az storage blob download --account-name $storage_account --container-name $storage_container --name $cert_blob --file /tmp/test.cert
2. 调整Ansible模块的认证方式
auth_source: auto可能会优先使用其他认证源(比如本地Azure CLI缓存的账户),导致未使用指定的服务主体。修改模块参数,明确指定服务主体认证:
- name: Download RDS Certificate azure.azcollection.azure_rm_storageblob: resource_group: "{{ resource_group }}" storage_account_name: "{{ storage_account }}" container: "{{ storage_container }}" blob: "{{ cert_blob }}" dest: "/tmp/{{ cert_blob }}" auth_source: service_principal # 明确指定服务主体认证 subscription_id: "{{ lookup('env', 'AZURE_SUBSCRIPTION_ID') }}" client_id: "{{ lookup('env', 'AZURE_CLIENT_ID') }}" secret: "{{ lookup('env', 'AZURE_SECRET') }}" tenant: "{{ lookup('env', 'AZURE_TENANT') }}" register: rds_certificate_downloaded until: rds_certificate_downloaded is succeeded retries: 2 delay: 10 # ignore_errors: true # 建议临时移除,以便查看明确错误
3. 检查存储账户的网络限制
存储账户如果配置了防火墙或虚拟网络限制,控制节点的IP不在允许列表内,也会触发AuthorizationFailure错误:
- 登录Azure Portal,进入目标存储账户 -> 网络配置
- 检查是否设置为"允许所有网络",如果是"选定网络",需将控制节点的公网IP添加到允许列表中。
4. 确认环境变量正确加载
执行Playbook前,先验证环境变量是否正确设置:
echo "Subscription ID: $AZURE_SUBSCRIPTION_ID" echo "Client ID: $AZURE_CLIENT_ID" echo "Tenant ID: $AZURE_TENANT"
确保所有变量都有正确的UUID值,没有为空或错误。
5. 临时使用存储账户密钥绕开RBAC测试
如果RBAC问题排查困难,可以临时用存储账户访问密钥测试,确认是否是RBAC的问题:
- name: Download RDS Certificate azure.azcollection.azure_rm_storageblob: resource_group: "{{ resource_group }}" storage_account_name: "{{ storage_account }}" container: "{{ storage_container }}" blob: "{{ cert_blob }}" dest: "/tmp/{{ cert_blob }}" storage_account_key: "{{ lookup('env', 'AZURE_STORAGE_ACCOUNT_KEY') }}" # 使用存储账户密钥 register: rds_certificate_downloaded until: rds_certificate_downloaded is succeeded retries: 2 delay: 10
若此方法成功,说明问题出在RBAC配置;若仍失败,需检查容器名称、Blob名称是否正确,或存储账户是否存在。
内容的提问来源于stack exchange,提问作者Amitabh Ghosh
相关产品推荐
相关产品推荐

