azure-arm-consumption:如何获取 CSP subscription 的消费数据
结论
对于 CSP subscription,已经产生的 Azure 消费明细应通过 ConsumptionManagementClient 的 usageDetails.list() 获取,不应使用 forecasts.list()。
forecasts.list() 返回的是消费预测。旧版 azure-arm-consumption 对该接口的支持有限,通常只适用于 EA subscription,因此不能用它查询实际用量。
获取消费明细
完成 Service Principal 登录并取得 credentials 后,以 subscription 为查询范围调用 usageDetails.list():
const MsRest = require('ms-rest-azure');
const {
ConsumptionManagementClient
} = require('azure-arm-consumption');
async function getConsumption() {
const credentials =
await MsRest.loginWithServicePrincipalSecret(
keys.appId,
keys.pass,
keys.tenantId
);
const client = new ConsumptionManagementClient(
credentials,
subscriptionId
);
const scope = `/subscriptions/${subscriptionId}`;
const result = await client.usageDetails.list(scope);
return result;
}
getConsumption()
.then(result => {
console.log(result);
})
.catch(error => {
console.error(error);
});
在部分旧版本 SDK 中,usageDetails.list() 不接收 scope,而是直接使用创建客户端时传入的 subscriptionId:
const result = await client.usageDetails.list();
具体应以项目所安装版本的 TypeScript 定义或 API 文档为准,不要混用这两种调用方式。
处理分页
消费明细可能分多页返回。分页字段会因 SDK 版本而异,常见的处理方式是读取 nextLink,再调用 listNext():
async function getAllUsageDetails(client, scope) {
const records = [];
let page = await client.usageDetails.list(scope);
records.push(...page);
while (page.nextLink) {
page = await client.usageDetails.listNext(page.nextLink);
records.push(...page);
}
return records;
}
如果返回对象不能直接作为数组展开,需要检查其中的 value、nextLink 等字段。不同版本的自动生成 SDK 可能采用不同的返回结构。
权限要求
Service Principal 必须拥有读取目标 subscription 消费数据所需的权限。只有普通资源读取权限时,接口仍可能返回 403 Forbidden。
需要确认以下事项:
- Service Principal 已分配到正确的 subscription。
- Service Principal 具有
Cost Management Reader、Billing Reader,或包含相应消费读取操作的自定义角色。 - CSP 租户、客户租户和订阅之间的授权关系正确。
- 查询的 subscription 属于当前认证上下文。
usageDetails 和账单数据的区别
usageDetails.list() 返回 Azure 使用量和费用明细,可用于统计某个 subscription 已经产生的消费,但这些数据不一定等同于 CSP 合作伙伴最终收到的账单:
- 数据可能存在延迟。
- 税费、合作伙伴折扣、信用额度和价格调整未必会完整体现。
- 最终结算金额可能与用量明细的汇总结果不同。
- CSP 跨客户对账通常需要通过 Partner Center 的账单或 reconciliation API 获取数据。
如果只需查看某个 CSP subscription 当前已经产生的 Azure 消费,可以使用 usageDetails.list()。如果需要合作伙伴级别的最终账单、发票或对账数据,则不能只依赖 azure-arm-consumption,还应使用相应的 Partner Center 账单接口。
备注:内容仅供参考。