Programmatically create Azure Enterprise Agreement subscriptions with the latest APIs

This article helps you programmatically create Azure Enterprise Agreement (EA) subscriptions for an EA billing account using the most recent API versions. If you're still using the older preview version, see Programmatically create Azure subscriptions legacy APIs.

In this article, you learn how to create subscriptions programmatically using Azure Resource Manager.

When you create an Azure subscription programmatically, it falls under the terms of the agreement where you receive Azure services from Microsoft or a certified seller. For more information, see Azure Legal Information.

Note

We recommend that you use the Azure Az PowerShell module to interact with Azure. See Install Azure PowerShell to get started. To learn how to migrate to the Az PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.

You can't create support plans programmatically. You can buy a new support plan or upgrade one in the Azure portal. Navigate to Help + support and then at the top of the page, select Choose the right support plan.

Prerequisites

A user must either have the Enterprise Administrator role or the Owner role on an Enrollment Account to create a subscription. There are two ways to get the Owner role on an Enrollment Account:

  • The Enterprise Administrator of your enrollment can make you an Account Owner (sign in required) which makes you an Owner of the Enrollment Account.
  • An existing Owner of the Enrollment Account can grant you access.

To use a service principal to create an EA subscription, an Owner of the Enrollment Account must grant that service principal the ability to create subscriptions.

When using a service principal to create subscriptions, use the ObjectId of the Microsoft Entra Enterprise application as the Service Principal ID using Microsoft Graph PowerShell or Azure CLI. You can also use the steps at Find your service principal and tenant IDs to find the object ID in the Azure portal for an existing service principal.

For more information about the EA role assignment API request, see Assign roles to Azure Enterprise Agreement service principal names. The article includes a list of roles (and role definition IDs) that can be assigned to a service principal.

Note

  • Ensure that you use the correct API version to give the enrollment account owner permissions. For this article and for the APIs documented in it, use the 2019-10-01-preview API.
  • If you're migrating to use the newer APIs, your previous configuration made with the 2015-07-01 version doesn't automatically convert for use with the newer APIs.
  • The Enrollment Account information is only visible when the user's role is Account Owner. When a user has multiple roles, the API uses the user's least restrictive role.

Find accounts you have access to

After you're added to an Enrollment Account associated to an Account Owner, Azure uses the account-to-enrollment relationship to determine where to bill the subscription charges. All subscriptions created under the account are billed to the EA enrollment that the account is in. To create subscriptions, you must pass in values about the enrollment account and the user principals to own the subscription.

To run the following commands, you must be logged in to the Account Owner's home directory, which is the directory that subscriptions are created in by default.

Request to list all enrollment accounts you have access to:

GET https://management.chinacloudapi.cn/providers/Microsoft.Billing/billingaccounts/?api-version=2020-05-01

The API response lists all enrollment accounts you have access to:

{
  "value": [
    {
      "id": "/providers/Microsoft.Billing/billingAccounts/1234567",
      "name": "1234567",
      "properties": {
        "accountStatus": "Unknown",
        "accountType": "Enterprise",
        "agreementType": "EnterpriseAgreement",
        "soldTo": {
          "companyName": "Contoso",
          "country": "CN "
        },
        "billingProfiles": {
          "hasMoreResults": false
        },
        "displayName": "Contoso",
        "enrollmentAccounts": [
          {
            "id": "/providers/Microsoft.Billing/billingAccounts/1234567/enrollmentAccounts/7654321",
            "name": "7654321",
            "type": "Microsoft.Billing/enrollmentAccounts",
            "properties": {
              "accountName": "Contoso",
              "accountOwnerEmail": "kenny@contoso.partner.onmschina.cn",
              "costCenter": "Test",
              "isDevTest": false
            }
          }
        ],
        "hasReadAccess": false
      },
      "type": "Microsoft.Billing/billingAccounts"
    }
  ]
}

The values for a billing scope and id are the same thing. The id for your enrollment account is the billing scope under which the subscription request is initiated. It's important to know the ID because it's a required parameter that you use later in the article to create a subscription.

Create subscriptions under a specific enrollment account

The following example creates a subscription named Dev Team Subscription in the enrollment account selected in the previous step.

Using one of the following methods, you create a subscription alias name. We recommend that when you create the alias name, you:

  • Use alphanumeric characters and hyphens
  • Start with a letter and end with an alphanumeric character
  • Don't use periods

An alias is used for simple substitution of a user-defined string instead of the subscription GUID. In other words, you can use it as a shortcut. You can learn more about alias at Alias - Create. In the following examples, sampleAlias is created but you can use any string you like.

If you have multiple user roles in addition to the Account Owner role, then you must retrieve the account ID from the Azure portal. Then you can use the ID to programmatically create subscriptions.

Call the PUT API to create a subscription creation request/alias.

PUT https://management.chinacloudapi.cn/providers/Microsoft.Subscription/aliases/{{guid}}?api-version=2021-10-01api-version=2021-10-01

In the request body, provide as the billingScope the id from one of your enrollmentAccounts.

{
  "properties": {
        "billingScope": "/providers/Microsoft.Billing/BillingAccounts/1234567/enrollmentAccounts/7654321",
        "DisplayName": "Dev Team Subscription", //Subscription Display Name
        "Workload": "Production"
  }
}

Allowed values for Workload are Production and DevTest.

Response

{
  "id": "/providers/Microsoft.Subscription/aliases/sampleAlias",
  "name": "sampleAlias",
  "type": "Microsoft.Subscription/aliases",
  "properties": {
    "subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
    "provisioningState": "Accepted"
  }
}

You can do a GET on the same URL to get the status of the request.

Request

GET https://management.chinacloudapi.cn/providers/Microsoft.Subscription/aliases/{{guid}}?api-version=2021-10-01

Response

{
  "id": "/providers/Microsoft.Subscription/aliases/sampleAlias",
  "name": "sampleAlias",
  "type": "Microsoft.Subscription/aliases",
  "properties": {
    "subscriptionId": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e",
    "provisioningState": "Succeeded"
  }
}

An in-progress status is returned as an Accepted state under provisioningState.

Create subscription and make subscriptionOwnerId the owner

When a service principal uses the Subscription Alias API to create a new subscription and doesn't include additionalProperties in the request, the service principal automatically becomes the owner of the new subscription. If you don't want the service principal to be the owner, you can specify subscriptionTenantId and subscriptionOwnerId in the additionalProperties. This process makes the specified subscriptionOwnerId the owner of the new subscription, not the service principal.

Sample request body:


{
    "properties": {
        "billingScope": "/providers/Microsoft.Billing/billingAccounts/{EABillingAccountId}/enrollmentAccounts/{EnrollmentAccountId}",
        "displayName": "{SubscriptionName}",
        "workLoad": "Production",
        "resellerId": null,
        "additionalProperties": {
            "managementGroupId": "",
            "subscriptionTenantId": "{SubscriptionTenantId}", // Here you input the tenant GUID where the subscription resides after creation
            "subscriptionOwnerId": "{ObjectId that becomes the owner of the subscription}", // Here you input the objectId which is set as the subscription owner when it gets created.
            "tags": {}
        }
    }
}

Create subscriptions in a different tenant

Using the subscription Alias REST API, you can create a subscription in a different tenant using the subscriptionTenantId parameter in the request body. Your Azure Service Principal (SPN) must get a token from its home tenant to create the subscription. After you create the subscription, you must get a token from the target tenant to accept the transfer using the Accept Ownership API.

For more information about creating EA subscriptions in another tenant, see Create subscription in other tenant and view transfer requests.

Use ARM template or Bicep

The previous section showed how to create a subscription with PowerShell, CLI, or REST API. If you need to automate creating subscriptions, consider using an Azure Resource Manager template (ARM template) or Bicep file.

The following ARM template creates a subscription. For billingScope, provide the enrollment account ID. The subscription is created in the root management group. After creating the subscription, you can move it to another management group.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "subscriptionAliasName": {
            "type": "string",
            "metadata": {
                "description": "Provide a name for the alias. This name will also be the display name of the subscription."
            }
        },
        "billingScope": {
            "type": "string",
            "metadata": {
                "description": "Provide the full resource ID of billing scope to use for subscription creation."
            }
        }
    },
    "resources": [
        {
            "scope": "/",
            "name": "[parameters('subscriptionAliasName')]",
            "type": "Microsoft.Subscription/aliases",
            "apiVersion": "2021-10-01",
            "properties": {
                "workLoad": "Production",
                "displayName": "[parameters('subscriptionAliasName')]",
                "billingScope": "[parameters('billingScope')]"
            }
        }
    ],
    "outputs": {}
}

Or, use a Bicep file to create the subscription.

targetScope = 'managementGroup'

@description('Provide a name for the alias. This name will also be the display name of the subscription.')
param subscriptionAliasName string

@description('Provide the full resource ID of billing scope to use for subscription creation.')
param billingScope string

resource subscriptionAlias 'Microsoft.Subscription/aliases@2021-10-01' = {
  scope: tenant()
  name: subscriptionAliasName
  properties: {
    workload: 'Production'
    displayName: subscriptionAliasName
    billingScope: billingScope
  }
}

Deploy the template at the management group level. The following examples show deploying the JSON ARM template, but you can deploy a Bicep file instead.

PUT https://management.chinacloudapi.cn/providers/Microsoft.Management/managementGroups/mg1/providers/Microsoft.Resources/deployments/exampledeployment?api-version=2020-06-01

With a request body:

{
  "location": "chinanorth3",
  "properties": {
    "templateLink": {
      "uri": "http://mystorageaccount.blob.core.chinacloudapi.cn/templates/template.json"
    },
    "parameters": {
      "subscriptionAliasName": {
        "value": "sampleAlias"
      },
      "billingScope": {
        "value": "/providers/Microsoft.Billing/BillingAccounts/1234567/enrollmentAccounts/7654321"
      }
    },
    "mode": "Incremental"
  }
}

To move a subscription to a new management group, use the following ARM template.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "targetMgId": {
            "type": "string",
            "metadata": {
                "description": "Provide the ID of the management group that you want to move the subscription to."
            }
        },
        "subscriptionId": {
            "type": "string",
            "metadata": {
                "description": "Provide the ID of the existing subscription to move."
            }
        }
    },
    "resources": [
        {
            "scope": "/",
            "type": "Microsoft.Management/managementGroups/subscriptions",
            "apiVersion": "2020-05-01",
            "name": "[concat(parameters('targetMgId'), '/', parameters('subscriptionId'))]",
            "properties": {
            }
        }
    ],
    "outputs": {}
}

Or, the following Bicep file.

targetScope = 'managementGroup'

@description('Provide the ID of the management group that you want to move the subscription to.')
param targetMgId string

@description('Provide the ID of the existing subscription to move.')
param subscriptionId string

resource subToMG 'Microsoft.Management/managementGroups/subscriptions@2020-05-01' = {
  scope: tenant()
  name: '${targetMgId}/${subscriptionId}'
}

Limitations of Azure Enterprise subscription creation API

  • Only Azure Enterprise subscriptions are created using the API.
  • There's a limit of 5,000 subscriptions per enrollment account. After that, more subscriptions for the account can only be created in the Azure portal. To create more subscriptions through the API, create another enrollment account. Canceled, deleted, and transferred subscriptions count toward the 5000 limit.
  • Users who aren't Account Owners, but were added to an enrollment account via Azure role-based access control, can't create subscriptions in the Azure portal.

Next steps