The Case of REST & Azure Resource Manager APIs

There are two kinds of people in this world. One who love ready made SDKs and then there are others who love to work on pure REST APIs. I’m from the 1st category. :)

The reason behind using SDKs is they include pure abstracted API calls. For example, if you use Active Directory Authentication Library (ADAL), it has AcquireTokenAsync method. This method, if you call, takes just couple of lines of code and makes your life much more easier.

However, behind the scenes, this method does a lot of stuff. For example, in case of Windows apps: calling WebAuthenticationBroker, launching Web UI, handling app navigation, etc. Similarly, it does same thing, in iOS and Android. But that entire code base is repetitive in every app which is going to use Active Directory for login. Now, one may ask, why so many calls are made just to authenticate and acquire token or as we progress through this blog post, why so many calls are required to perform basic operations. The answer lies in purity of REST APIs. And ADAL makes life easier here by providing one method doing all this for you while abstracting all the details.

When I was working on my blog post Monitor Azure Resource Usage and Predict Expenses, there was no SDK available for Azure Resource Manager (ARM) and the old API was not an ideal way to handle Resource Management APIs.

So, I had to write an app from scratch to get ARM working in my sample and here my friend Gaurav Mantri (@gmantri) helped me a lot. Gaurav founded Cloud Portam, which helps to manage resources in Azure like Storage, Search, etc… Thanks to him, I could understand the flow and I’m going to put it here on this blog post.

Step 1: Authenticate with Common

ARM allows you to manage resources within subscription and subscription is now part of your Active Directory. So, the first thing that you need to do is to authenticate with right Active Directory. This is simple if you’ve just one subscription and one Active Directory in your subscription, but if you’ve multiple subscriptions/active directories, you may want to iterate through them and get separate access tokens. To avoid this, first we hit the ‘common’ endpoint and then get the Tenants available.

Step 2: Get Tenants

As a user, your user account may be associated with multiple active directories. A tenant is nothing but an active directory to which you have access. Here, in this step we get all active directories first by calling below method. Later on we’ll try to fetch subscription (if available) from each directory.

private async Task GetTenants()
{
var requestUrl = "https://management.azure.com/tenants?api-version=2015-01-01";
try {
var tenantResponse = await client.GetStringAsync(requestUrl);
tenantCollection = JsonConvert.DeserializeObject<TenantResponse> (tenantResponse);
}
catch (Exception ex) {
await DisplayAlert("Error!", ex.Message, "Dismiss");
}
foreach (var tenant in tenantCollection.TenantCollection) {
await GetSubscriptions (tenant.TenantId);
}
}

Step 3: Get Subscriptions

Once we get tenants, each tenant may have subscription on which we may want perform some actions. To do so, we pass each tenant ID from GetTenants() to this method and acquire new token silently (without login prompt)

private async Task GetSubscriptions(string tenantId)
{
var requestUrl = "https://management.azure.com/subscriptions?api-version=2015-01-01";
try {
var data = await DependencyService.Get<IAuthenticator> ().AuthenticateSilently (tenantId,
App.ManagementResourceUri, App.ClientId);
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", data.AccessToken);
var subsriptionResponse = await client.GetStringAsync (requestUrl);
var subscriptions = JsonConvert.DeserializeObject<SubscriptionResponse>(subsriptionResponse);
foreach (var subscription in subscriptions.SubscriptionCollection) {
SubscriptionCollection.Add(subscription); }
IsFirstRunComplete = true; }
catch (Exception ex) {
await DisplayAlert("Error!", ex.Message, "Dismiss"); }
}

Step 4: Call ARM APIs

In order to perform management operations on an Azure Subscription, a user must be authenticated and authorized. Authentication part is handled by Azure Active Directory. There is a one to many relationship between an Azure AD and Azure Subscription. i.e. an Azure AD can be used as an authentication store for many Azure Subscriptions however authentication for an Azure Subscription can happen only with a single Azure AD. Once a user is authenticated with an Azure AD, next step is to find out a list of Azure Subscriptions the logged in user has access to. This is what we’re doing in this step. What a user can do in each of these subscriptions (i.e. the authorization part) can be accomplished by using Azure Resource Manager (ARM) API’s Role-based access control (RBAC).

var requestUrl = String.Format("https://management.azure.com/subscriptions/{0}/providers/Microsoft.Commerce/UsageAggregates?
api-version=2015-06-01-preview&reportedStartTime={1}&reportedEndTime={2}&aggregationGranularity=Daily&showDetails=false",
App.SelectedSubscription.SubscriptionId, startTime, endTime);
var usageData = await client.GetStringAsync (requestUrl);
var data = JsonConvert.DeserializeObject<AzureTracker.Model.UsageResponse> (usageData);

Now you can replace your code in Step 4 to manage or monitor resources in your Azure subscription, but the flow will not change. The entire list of APIs covering resources and possible operations on them is available here

I hope this post will helps you to understand the model behind ARM API calls.

Namaste,
Mayur Tendulkar

Published by

Mayur Tendulkar

Struggling Juggler at Dyte

4 thoughts on “The Case of REST & Azure Resource Manager APIs”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.