Eh HELP!? Creating & Sorting Chaos in Azure Subscriptions Automation
Tags: help, azure, cloud
Published: 2020-07-16 23:28:30

---
title: Eh HELP!? Creating & Sorting Chaos in Azure Subscriptions Automation
published: true
description: I'm trying to accomplish a simple task, outlined in the docs for completing this simple task of creating an Azure...
tags: help, azure, cloud
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/y3ife3eyu9trut5y3iw5.jpeg
---
I'm trying to accomplish a simple task, outlined in the docs for completing this simple task of creating an Azure [subscription with the Azure REST API](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/programmatically-create-subscription?tabs=rest). Currently I'm using Postman and have gone through these steps that Jon Gallant put together - excellent [video](https://youtu.be/fh37VQ3_exk) and [blog](https://blog.jongallant.com/2017/11/azure-rest-apis-postman/) entry on the topic - and have had success with connecting via service principal, getting an AAD Token and pulling a list of resource groups. Which in my particular video below I put together, I show all of this working and the singular resource group I get returned from Azure.

{% youtube SuXl7FuY4tY %}

Again though, I'm trying to create a subscription. I have ownership permissions in active directory and created the service principal I'm using with that user account. Is there another place to put this? Is there some permissions or something particular I'm supposed to assign to the service principal?

## Then I Thought

Oh, it seemed I needed to add the permissions, maybe they weren't inherited from the user who creates the service principal or just additional ones were needed. I read a bit more in the doc and noted this:

> An existing Owner of the Enrollment Account can grant you access. Similarly, if you want to use a service principal to create an EA subscription, you must grant that service principal the ability to create subscriptions.

The part "you must grant that service principal the ability to create subscriptions" and I thought, aha, got it! So I dig this. Using the az CLI issuing this command as detailed in the [docs](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/grant-access-to-create-subscription).

I checked which accounts I have access to with

```shell
az billing enrollment-account list
```

and I got this response.

```json
[
  {
    "id": "/providers/Microsoft.Billing/enrollmentAccounts/7760268a-blah-blah-this-secretdf64c9",
    "name": "7760268a-blah-blah-this-secretdf64c9",
    "principalName": "azure-test@company.com",
    "type": "Microsoft.Billing/enrollmentAccounts"
  }
]
```

Then I ran the command to add the permissions using the id/name/princpal name available in the previous results.

```shell
az role assignment create --role Owner --assignee-object-id <userObjectId> --scope /providers/Microsoft.Billing/enrollmentAccounts/<enrollmentAccountObjectId>
```

I filled in the parameters, in spite of their confusing nature to not be mapped by name to the things I'm filling them in with. i.e. The keys in the list: `id`, `name`, `principalName`, and `type` don't map to `userObjectId`, or `enrollmentAccountObjectId`. The response I got back with what I entered into the command is confusing, to say the least.

```json
{
  "canDelegate": null,
  "id": "/providers/Microsoft.Billing/enrollmentAccounts/7760268a-blah-blah-this-secretdf64c9/providers/Microsoft.Authorization/roleAssignments/9d682424-blah-blah-this-secretac9f92",
  "name": "9d682424-blah-blah-this-secretac9f92",
  "principalId": "47f9be37-blah-blah-this-secret2c1566",
  "principalName": "adron.hall@company.com",
  "principalType": "User",
  "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-blah-blah-this-secretbcb635",
  "roleDefinitionName": "Owner",
  "scope": "/providers/Microsoft.Billing/enrollmentAccounts/7760268a-blah-blah-this-secretdf64c9",
  "type": "Microsoft.Authorization/roleAssignments"
}
```

The first thing I noticed is that this principal name is the email of the other account, not associated (theoretically) with the service principal that executed this request. Oh well I figured this was what it is supposed to be, but with `canDelegate` set to null, and nothing that really shows a "successfully added permissions" I wasn't sure if this is what I should have expected. I pushed forward anyway.

Next step is to see if I can create a subscription with this newly assigned (theoretically) power for this service principal! Charge! I executed the following using the Azure CLI first.

```
az account create --offer-type "MS-AZR-0017P" --display-name "Dev Team Subscription" --enrollment-account-object-id "<enrollmentAccountObjectId>" --owner-object-id "<userObjectId>","<servicePrincipalObjectId>"
```

This is another part of the confusing array of things we have to keep track of, let's discuss. The `--offer-type "MS-AZR-0017P"` is highly arbitrary, but I get it, you just use one of the options from the docs. So I'm sticking with `"MS-AZR-0017P"` as shown. The next thing is the display name, cool I'll just make up one.

Now time for the more confusing bits, first up is the `enrollmentAccountObjectId`. Per the enrollment account item above that I pulled, I'm guessing this is either this value "/providers/Microsoft.Billing/enrollmentAccounts/7760268a-blah-blah-this-secretdf64c9" which has a key of `id` or maybe it's just the `id` within the id, the UUID segment `7760268a-blah-blah-this-secretdf64c9`? I'm not sure, but I'll start with just `7760268a-blah-blah-this-secretdf64c9` as that seems to be the running case, mostly, sometimes, throughout the CLI use.

Now the `userObjectId` which I'll guess is the item in the enrollment account keyed `name`. Not that `name` and `userObjectId` actually map but they're both UUIDs so that seems to sync based on the other command above, sort of. Then finally I'll need the `servicePrincipalObjectId`, which now what is the easiest way to get that? Oh, I remembered that this is usually keyed as an `appId` not a service principal id, so I ran the following command, and have added some `jq` magic to make it easier to see just the appId.

```shell
az ad sp list --display-name azure-astra | jq '.[0] | {appId}'
```

Using that for the service principal object ID I executed the now finalized command and got this response!

```shell
az account: 'create' is not in the 'az account' command group. See 'az account --help'. If the command is from an extension, please make sure the corresponding extension is installed. To learn more about extensions, please visit https://docs.microsoft.com/en-us/cli/azure/azure-cli-extensions-overview
```

Ok, that's definitely not what I expected. So now I need an [extension](https://docs.microsoft.com/en-us/cli/azure/azure-cli-extensions-overview) to create this thing. Alright, check. I read that doc and pulled up a list of extensions.

```shell
az extension list-available --output table
```

That gave me a big ole' list to choose from. I went through and read them, and decided that the `subscription` extension was probably what I wanted. I ran `az extension add --name subscription` and as a response got the following.

```shell
The installed extension 'subscription' is in preview.
```

This seems to make sense, since the subscription API/CLI/REST end points are labeled as in preview. Ok, moving forward. Time to rerun the command again.

```shell
az account create --offer-type "MS-AZR-0017P" --display-name "New Magical Subscription" --enrollment-account-object-id "7760268a-blah-blah-this-secretdf64c9" --owner-object-id "7760268a-blah-blah-this-secretdf64c9"
```

Suspense ensues. I see the CLI message.

```shell
 - Running ..
```

This time the response, after about ~20 seconds comes back as.

```shell
{- Finished ..
  "subscriptionLink": "/subscriptions/2afc30a5-8c4a-49cd-ab8e-d05d376e8ef0"
}
```

Ok, so it worked with the CLI. It seems. Let's get it to work with the REST API now. First things first, we need to confirm that the accounts are accessible via the REST API that we want to add the subscription to.

That includes a GET requests against the URI `https://management.azure.com/providers/Microsoft.Billing/enrollmentAccounts?api-version=2018-03-01-preview`. Making that request, using the token created as above in Jon Gallant's email, gives me an empty array JSON response.

So I'm still stuck. What is it that needs to be done to fix this service principal so that I can use the REST API to create a subscription? To note, I need to use the API, not the CLI for what I'm working on building. Which it is nice that the CLI completed the action but it clearly is working in a different way than the API requires.

Help me Obi Wan Kenobi!