Creating Customer subscriptions under an Azure plan using the REST API
A few months ago Microsoft announced the new commerce experience for CSP. (If you missed it, read up on it here). With that new experience also came the Microsoft Partner Agreement and Microsoft Customer Agreement. And as a result the management of Azure Subscriptions is (somewhat) simplified.
We're now talking about creating an "Azure Plan" through Partner Center. Within that plan we can create an Azure Subscription. The cool thing here is that you no longer need Partner Center to create subscriptions for your customers. as a Service Provider, once the Azure Plan is in place you can create subscriptions through the Azure Portal. More stuff related to billing, permissions and partner earned credits have changed significantly with the introduction of the new Microsoft Agreements and the Azure Plans, so I do recommend reading up on them :)
As an added bonus, we can now create subscriptions through the Rest API without having to deal with Partner Center (and it's APIs). Similar to what was already possible for EA enrollments.
I thought I'd give it a shot and do a short write-up of my findings. You can find the official documentation here. My goal was to do this through PowerShell as there are currently no PowerShell modules to accomplish this for an MCA or MPA and use the code for other automation purposes in the future.
Before you get started, make sure you have the required roles in place to actually manage subscriptions and billing for Azure Plans (https://docs.microsoft.com/en-us/azure/billing/billing-understand-mca-roles). On the CSP side you need to make sure you are either a Global Admin or an Admin Agent.
The Code
TL;DR: You can find the script here: https://github.com/whaakman/azureplan-billing-and-cost-management-api
Also note that this is only about creating subscriptions. If you're moving forward you might want to look into building some logic around checking for existing subscriptions, naming conventions, etc.
Basically we're just going to fire a bunch of request tot he REST API's and use PowerShell to filter out values we need for each new request.
Make sure you're logged into Azure (Login-AzAccount) with the credentials that have sufficient access. First we build the Authentication Header we're going to use for the requests:
$azContext = Get-AzContext
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
$token = $profileClient.AcquireAccessToken($azContext.Subscription.TenantId)
$authHeader = @{
'Content-Type'='application/json'
'Authorization'='Bearer ' + $token.AccessToken
}
Right.. Let's get started. The first piece of information we need are the billing accounts we have access to.
In the official documentation it states you need an "agreementType" of "MicrosoftPartnerAgreement". In reality, this is never returned by the API. What we are looking for is the Billing Account which has the "accountType" set to "Partner" and the "agreementType" set to "MicrosoftCustomerAgreement".
$restUriBillingAccounts = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts?api-version=2019-10-01-preview"
# Retreive the Billing Accounts you have access to
$restUriBillingAccountsResponse = Invoke-RestMethod -Uri $restUriBillingAccounts -Method Get -Headers $authHeader
# Filter Billing Account Name for the Microsoft Customer Agreement / Partner
$billingAccountName = ($restUriBillingAccountsResponse.value| Where-Object {$_.properties.agreementType -like "MicrosoftCustomerAgreement"}).name
This will result in the following (I know it's a lot of redacted information but I want to point out that the information you need is there):
For the second part we need to get a list of all the customers and filter out the "customerId" which we need to create the CSP subscription within the Azure Plan.
# Retreive the customers your billing account has access to
$restUriCustomers = "https://management.azure.com/providers/Microsoft.Billing/billingAccounts/$billingAccountName/customers?api-version=2019-10-01-preview"
$restUriCustomersResponse = Invoke-RestMethod -Uri $restUriCustomers -Method Get -Headers $authHeader
# Filter the customerid
$customerId = ($restUriCustomersResponse.value | Where-Object {$_.properties.displayName -like "$customerName"}).id
I've chosen to parse my customer name as parameter and store it in "$customerName" but hard coding it works as well. Using the Customer Name we're filtering the right customer and then storing the customerId in "$customerId".
Last but not least we can create the subscription. As a second parameter I'm storing the subscription name as "$subscriptionName" for use during the subscription creation process.
$restUriCreateSubscription = "https://management.azure.com"+ $customerId +"/providers/Microsoft.Subscription/createSubscription?api-version=2018-11-01-preview"
$bodyCreateSubscription = @"
{
"displayName" : "$subscriptionName",
"skuId" : "0001"
}
"@
$createSubscriptionResponse = Invoke-RestMethod -Uri $restUriCreateSubscription -Method Post -Body $bodyCreateSubscription -Headers $authHeader
$createSubscriptionResponse
Unlike the documentation suggest, the API does not give any feedback or result. But going to the actual customer tenant and listing the subscription (or checking through Partner Center) confirms that the subscription has been created.
Additionally, the Foreign Principal (for use by the Admin Agent) role is created and you can access the subscription like you normally would. But of course you would now add a delegation using Azure Lighthouse :)