Azure CLI:固定 tenant、subscription 与资源组落点
Azure CLI 登录得到的是 Microsoft Entra 身份与可见订阅集合,资源操作最终落在哪个 subscription 和 resource group,还取决于活动订阅与每条命令的参数。可靠脚本不依赖上一次终端留下的默认值。
tenant 决定身份归属,subscription 决定资源落点
az login 可能返回多个 tenant 与 subscription。az account show 展示当前活动订阅,az account set 会修改后续命令的默认落点;多数资源命令还能用 --subscription 显式覆盖。一次变更前至少固定 tenantId、subscription ID、资源组和位置。
az version
az login --tenant "$EXPECTED_TENANT_ID"
az account set --subscription "$EXPECTED_SUBSCRIPTION_ID"
az account show --query '{tenant:tenantId,subscription:id,user:user.name}' --output json人员交互登录需要满足组织的 MFA 与条件访问。无人值守脚本不要保存用户名密码,优先使用 managed identity、workload identity federation 或权限受限的 service principal。登录方式改变时,缓存与刷新 token 的安全边界也会改变。
安装与账号缓存需要独立基线
CLI 来源、扩展和 Python 运行组件都会影响命令行为。镜像或开发机记录 az version 与 az extension list,扩展按批准清单安装,不允许命令静默拉取未经审查的扩展。配置目录包含账号缓存、cloud 和默认值,应避免跨项目共享。
AZURE_CONFIG_DIR="$PWD/.tmp/azure-cli" az account show
AZURE_CONFIG_DIR="$PWD/.tmp/azure-cli" az login --tenant "$EXPECTED_TENANT_ID"
AZURE_CONFIG_DIR="$PWD/.tmp/azure-cli" az account list --output json隔离目录的第一次 account show 应失败,这能证明脚本没有借用开发机旧会话。CI 作业结束删除临时目录前,先确认它位于工作区明确路径,并让云端会话按组织策略到期或撤销。
正向查询与越权拒绝共同证明 RBAC
正向实验在指定 subscription 和资源组查询一个开发资源,输出完整资源 ID、location 与 tags。反向实验尝试读取未授权资源组或执行不在角色内的写动作,预期得到 AuthorizationFailed。错误中携带的 correlation/request 信息要进入工单与活动日志查询。
az resource list \
--subscription "$EXPECTED_SUBSCRIPTION_ID" \
--resource-group "$EXPECTED_RESOURCE_GROUP" \
--query '[].{id:id,location:location,type:type,tags:tags}' \
--output json
az group delete \
--subscription "$EXPECTED_SUBSCRIPTION_ID" \
--name intentional-deny-canary \
--yes资源不存在与权限拒绝是两类证据。反向对象应由测试环境专门准备,不能用生产资源组试错。角色分配传播存在延迟时,先刷新账号缓存并核对 scope,不能直接扩大到 subscription Owner。
查询格式和资源 ID 是自动化边界
Azure CLI 的 JSON 输出与 JMESPath --query 适合脚本,table 只用于人读。资源 ID 自带 subscription、resource group、provider、type 和 name,是连接脚本、审计与清理的稳定主键。脚本不要只保存显示名称,也不要从终端彩色输出中截取字段。
变更入口先比较 az account show 与期望 tenant/subscription,再验证目标资源 ID 前缀与标签。资源创建使用显式 --subscription、--resource-group 和 --location,并写入 owner、environment、expires-at。--yes 只能在前置守卫、审批和备份都成立后出现。
$account = az account show --output json | ConvertFrom-Json
if ($account.tenantId -ne $env:EXPECTED_TENANT_ID) { exit 42 }
if ($account.id -ne $env:EXPECTED_SUBSCRIPTION_ID) { exit 43 }
az group show --name $env:EXPECTED_RESOURCE_GROUP --output json工作负载身份与报告数据要分层治理
人员、managed identity、service principal 和联邦身份分别拥有不同生命周期。CI 信任钉住 issuer、subject、audience 与目标环境,角色 scope 尽量落在资源组或具体资源。部署身份与成本盘点身份分开,读取密钥库的权限也不因“脚本方便”附加给普通资源操作。
debug 输出、access token、资源 ID、订阅名称和 Activity Log 都属于敏感数据。日志上传前脱敏,artifact 设置访问与保留。容量来自订阅数、Region、资源提供程序、分页与重试,费用则来自资源本身、诊断设置、出口流量、备份和未释放的公网 IP。
logout、account clear 与资源删除不是一件事
az logout 移除登录会话,az account clear 清理订阅缓存;它们不会删除资源、角色分配、应用注册或联邦凭据。退出工具前先停止流水线,盘点资源组、locks、角色与策略,按依赖完成删除或移交,再处理本地缓存和工作负载身份。
az logout
az account clear
az account show最后一条应失败。误删恢复依赖资源类型自身的软删除、备份、锁和导出,不依赖 CLI 历史。长期治理记录 tenant/subscription owner、资源组契约、角色 scope、扩展版本、拒绝金丝雀和清理演练,让 Azure CLI 的每次操作都能回到明确落点。
