如何通过 CSP Partner Center API 创建 Azure Subscription?
结论
可以先通过 Partner Center API 创建 CSP Azure 订阅,再通过 Azure Resource Manager(ARM)API 部署 VM。客户通常不需要填写信用卡,也不需要进入 Azure Portal 创建订阅。
整个过程分为两个独立环节:
- Partner Center API 用于购买 Azure plan、创建 Azure subscription entitlement,并建立 CSP 计费关系。
- ARM API 用于在该 Azure subscription 中创建资源。调用 ARM 的身份必须存在于客户租户中,并拥有该订阅的 Azure RBAC 权限。
通过 Partner Center 创建订阅后,调用方不会自动获得 ARM 部署权限。很多集成问题出在第二步,并非订阅本身不可用。
为什么 Portal 会要求填写信用卡
CSP Azure 订阅由 CSP partner 或 indirect provider 结算,客户不需要再为该订阅绑定信用卡。
如果 Portal 要求补充 subscription profile 或付款方式,常见原因包括:
- 登录 Azure Portal 时选择了错误的 Microsoft Entra tenant。
- Portal 正在引导用户创建新的 Pay-As-You-Go 订阅,而不是使用已有的 CSP 订阅。
- Azure entitlement 仍在 provisioning,尚未形成可用的 ARM subscription。
- 当前用户没有 CSP 订阅的 RBAC 权限,因此 Portal 不会显示该订阅。
- Partner Center 中只创建了 Azure plan 商业订阅,没有在该 plan 下创建 Azure entitlement。
- CSP 商业关系、Microsoft Customer Agreement 或必要的客户确认尚未完成。
不要填写信用卡来「激活」CSP 订阅,否则可能会创建另一份与 CSP 计费无关的 Azure 订阅。
正确的对象关系
在 Azure plan 模型中,需要区分以下对象:
Customer
└── Azure plan Partner Center 中的计费容器
└── Azure entitlement 对应一个实际 Azure subscription
└── Resource group
└── Virtual machine
Partner Center 中名为 Azure plan 的 subscription 通常只是计费容器。调用 ARM API 时,真正需要的是 Azure entitlement 对应的 Azure subscription ID。
如果只创建了 Azure plan,没有创建 entitlement,就不能使用 Azure plan 的 Partner Center subscription ID 部署 VM。
推荐流程
1. 创建客户并建立商业关系
通过 Partner Center API 创建客户,并确认已经完成当前 CSP 模型要求的以下事项:
- reseller relationship;
- Microsoft Customer Agreement 确认;
- indirect reseller 与 indirect provider 之间的必要关系;
- 客户租户和默认域创建。
客户创建完成后,保存其 Microsoft Entra tenant ID。后续从客户租户申请 ARM token 时会用到这个 ID。
2. 获取 Azure plan 的可售目录项
产品、SKU、availability 和 catalogItemId 可能随市场、CSP 类型和 Partner Center 当前目录变化,因此不应硬编码在程序中。
应查询客户所在市场的 Partner Center catalog,找到 Azure plan,再使用返回的 catalogItemId 创建订单。
订单结构示例如下:
POST https://api.partnercenter.microsoft.com/v1/customers/{customerId}/orders
Authorization: Bearer {partnerCenterAccessToken}
Content-Type: application/json
Accept: application/json
{
"referenceCustomerId": "{customerId}",
"lineItems": [
{
"lineItemNumber": 0,
"offerId": "{catalogItemId}",
"friendlyName": "Customer Azure Plan",
"quantity": 1
}
]
}
具体字段应以当前 Partner Center Azure plan 订单模型为准。不要用历史 Azure offer 的固定 ID 代替目录查询结果。
3. 在 Azure plan 下创建 Azure entitlement
取得 Azure plan 的 Partner Center subscription ID 后,在该 plan 下创建供客户实际使用的 Azure subscription。
典型请求如下:
POST https://api.partnercenter.microsoft.com/v1/customers/{customerId}/subscriptions/{azurePlanSubscriptionId}/azureEntitlements
Authorization: Bearer {partnerCenterAccessToken}
Content-Type: application/json
Accept: application/json
{
"friendlyName": "Production Subscription"
}
随后查询 entitlement:
GET https://api.partnercenter.microsoft.com/v1/customers/{customerId}/subscriptions/{azurePlanSubscriptionId}/azureEntitlements
Authorization: Bearer {partnerCenterAccessToken}
Accept: application/json
响应中的 Azure subscription 标识才是调用 ARM API 时使用的 ID:
/subscriptions/{azureSubscriptionId}
创建过程可能异步执行。必须等到 entitlement 状态可用,并确认 ARM 已经能够查询对应的 subscription,才能继续部署 VM。不要在 Partner Center 返回创建成功后立即开始部署。
不同 Partner Center API 版本或合作伙伴类型使用的资源字段可能略有差异,应以实际响应中表示 Azure subscription/resource identifier 的字段为准。
两类 API 必须使用不同的 access token
Partner Center token
Partner Center API 使用面向 Partner Center 的 token:
POST https://login.microsoftonline.com/{partnerTenantId}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={appId}
&client_secret={clientSecret}
&grant_type=client_credentials
&scope=https%3A%2F%2Fapi.partnercenter.microsoft.com%2F.default
这个 token 只能调用 Partner Center API,不能直接用于 ARM。
ARM token
ARM token 必须从客户租户申请,audience/scope 应指向 Azure Resource Manager:
POST https://login.microsoftonline.com/{customerTenantId}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={appId}
&client_secret={clientSecret}
&grant_type=client_credentials
&scope=https%3A%2F%2Fmanagement.azure.com%2F.default
取得 token 后,使用它调用:
GET https://management.azure.com/subscriptions/{azureSubscriptionId}?api-version={supportedApiVersion}
Authorization: Bearer {armAccessToken}
如果返回 401,通常说明 token 的租户、audience 或应用凭据有误。
如果返回 403,通常说明身份验证已经成功,但应用对应的 service principal 没有该订阅的 Azure RBAC 权限。
必须解决客户租户中的身份和 RBAC
通过 client credentials 调用客户的 ARM,至少要满足以下条件:
- 应用在客户 tenant 中存在 service principal;
- 客户已经给予必要的租户级同意;
- 该 service principal 在目标 subscription 或 resource group 上具有 Azure RBAC role assignment;
- 申请 ARM token 时使用客户 tenant ID,而不是只使用 partner tenant ID。
角色应按最小权限原则分配。仅需创建和管理 VM 时,可以组合使用:
Virtual Machine ContributorNetwork ContributorManaged Identity Operator,如果 VM 使用托管身份- 目标 resource group 所需的其他权限
初次验证时也可以临时使用 Contributor,但该角色不能向其他主体授予 Azure RBAC 权限。验证完成后,应缩小权限范围。
创建角色分配的 ARM 请求示例如下:
PUT https://management.azure.com/subscriptions/{azureSubscriptionId}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentGuid}?api-version={supportedApiVersion}
Authorization: Bearer {bootstrapAccessToken}
Content-Type: application/json
{
"properties": {
"roleDefinitionId": "/subscriptions/{azureSubscriptionId}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionGuid}",
"principalId": "{customerTenantServicePrincipalObjectId}",
"principalType": "ServicePrincipal"
}
}
执行该请求的引导身份必须已经拥有 Owner、User Access Administrator 或其他能够创建角色分配的权限。
还要注意,GDAP 是 Microsoft 365/客户租户的委派管理关系,不等同于 Azure subscription 上的 RBAC。Azure 管理权限仍需通过 Azure RBAC、适用的 CSP 委派机制或 Azure Lighthouse 明确配置。
使用 ARM API 创建 VM
开始部署资源前,先确认以下调用能够成功:
GET https://management.azure.com/subscriptions/{azureSubscriptionId}?api-version={supportedApiVersion}
首先创建 resource group:
PUT https://management.azure.com/subscriptions/{azureSubscriptionId}/resourcegroups/app-production?api-version={supportedApiVersion}
Authorization: Bearer {armAccessToken}
Content-Type: application/json
{
"location": "eastasia"
}
然后依次创建:
- Virtual network 和 subnet
- Public IP(如果需要)
- Network interface
- VM、磁盘和相关扩展
VM 请求示例如下:
PUT https://management.azure.com/subscriptions/{azureSubscriptionId}/resourceGroups/app-production/providers/Microsoft.Compute/virtualMachines/app-vm-01?api-version={supportedApiVersion}
Authorization: Bearer {armAccessToken}
Content-Type: application/json
{
"location": "eastasia",
"properties": {
"hardwareProfile": {
"vmSize": "Standard_B2s"
},
"storageProfile": {
"imageReference": {
"publisher": "Canonical",
"offer": "0001-com-ubuntu-server-jammy",
"sku": "22_04-lts-gen2",
"version": "latest"
},
"osDisk": {
"createOption": "FromImage"
}
},
"osProfile": {
"computerName": "app-vm-01",
"adminUsername": "azureadmin",
"linuxConfiguration": {
"disablePasswordAuthentication": true,
"ssh": {
"publicKeys": [
{
"path": "/home/azureadmin/.ssh/authorized_keys",
"keyData": "{sshPublicKey}"
}
]
}
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "/subscriptions/{azureSubscriptionId}/resourceGroups/app-production/providers/Microsoft.Network/networkInterfaces/app-vm-01-nic"
}
]
}
}
}
api-version 应选择各 Azure resource provider 当前支持的稳定版本,不要将示例版本长期写死。部署前还需要注册所需的 provider,例如:
POST https://management.azure.com/subscriptions/{azureSubscriptionId}/providers/Microsoft.Compute/register?api-version={supportedApiVersion}
Authorization: Bearer {armAccessToken}
通常还需要注册:
Microsoft.Compute
Microsoft.Network
Microsoft.Storage
Microsoft.ManagedIdentity
provider 注册也可能异步完成。
是否能做到完全不跳转 Microsoft Portal
资源购买、订阅创建、RBAC 配置和 VM 部署都可以通过 API 完成。
但能否完全不出现 Microsoft 页面,取决于前置关系是否已经建立。以下操作可能需要客户管理员完成一次交互确认:
- CSP reseller relationship;
- Microsoft Customer Agreement;
- 应用的 Microsoft Entra admin consent;
- Azure Lighthouse onboarding 或其他委派授权。
这些操作涉及授权或合同确认,无法通过普通后台 API 静默绕过。一次性授权完成后,日常创建 Azure entitlement 和部署资源可以由应用后台自动执行。
排查顺序
可以按以下顺序检查:
- Partner Center 中是否创建了 Azure plan,而不是其他订阅产品。
- Azure plan 下是否存在状态可用的 Azure entitlement。
- 当前使用的是否为 entitlement 对应的 Azure subscription ID。
- ARM token 是否从客户 tenant 获取。
- token 的 scope 是否为
https://management.azure.com/.default。 - 应用的 service principal 是否存在于客户 tenant。
- service principal 是否在目标 subscription/resource group 上拥有 RBAC 权限。
GET /subscriptions/{id}是否成功。- 所需 resource provider 是否已经注册。
- 客户所在区域、配额和 CSP offer 是否允许使用目标 VM SKU。
需要完成的并不是让客户补充信用卡资料,而是打通「Azure plan → Azure entitlement → 客户租户身份 → Azure RBAC → ARM 部署」这条链路。
备注:内容仅供参考。