Getting access to Azure programmatically using the Azure SDK Management Libraries

This wasn't the blog post I wanted to write. I actually have a long draft of a blog post about the new Azure Elastic Databases that are currently in preview. All I needed before publishing it was an example of adding databases to an elastic database pool programmatically. That turned out to be a little more work than I had initially thought!

So rather than making a mess of my elastic databases post I decided to write another one first, showing how to allow Azure SDK Management Libraries like this one to access your Azure subscriptions.

What we want to achieve

I mentioned that I wanted to use the Azure SDK to automate creating databases and adding them to an Elastic Databases pool. In this example we will keep it a little simpler, and just list all SQL servers in a resource group. It's a little simpler, but the basic idea is the same.

We'll start with the code

I've put together a small example, take a look at the code and we will our way back from there, going through the steps required to make it work and fill in the blanks.

The example uses Microsoft Azure SQL Management Library pre-release.

using System;
using System.Net.Http;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Azure.Management.Resources;
using Microsoft.Azure.Management.Sql;

namespace ElasticDatabases
{
    class Program
    {
        private static string azureActiveDirectoryInstance = "https://login.microsoftonline.com/";
        private static string tenant = "<tenant name>.onmicrosoft.com";
        private static string clientId = "<client id>";
        private static string appKey = "<app key>";
        private static string resource = "https://management.core.windows.net/";
        private static string resourceGroup = "<resource group>";
        private static string subscriptionId = "<subscription id>";

        static string authority = azureActiveDirectoryInstance + tenant;

        static void Main(string[] args)
        {
            var client = GetSqlManagementClient();
            var servers = client.Servers.List(resourceGroup);
            foreach (var server in servers)
                Console.WriteLine(server.Name);

            Console.ReadLine();
        }

        private static string GetToken()
        {
            var httpClient = new HttpClient();
            var authContext = new AuthenticationContext(authority);
            var clientCredential = new ClientCredential(clientId, appKey);    
            var result = authContext.AcquireToken(resource, clientCredential);
            return result.AccessToken;
        }

        private static SqlManagementClient GetSqlManagementClient()
        {
            var token = GetToken();
            var credentials = new Microsoft.Azure.TokenCloudCredentials(subscriptionId, token);
            var client = new SqlManagementClient(credentials);
            return client;
        }
    }
}

The code creates a new SqlManagementClient using an Active Directory issued token to access a resource group in an Azure subscription, and list all the SQL servers inside that resource group.

Let's fill in the blanks

You've probably noticed the variables at the top of the code. Let's get to work figuring out what we need to get in there to make the example work.

  • azureActiveDirectoryInstance
  • tenant
  • clientId
  • appKey
  • resource
  • resourceGroup
  • subscriptionId

We can get a couple of them out of the way immediately. First of all "azureActiveDirectoryInstance". This refers to the instance of Azure you are using. Unless you are using a "special Azure instance" like the chinese or government Azure instances you can just go ahead and leave it as it is.

We've got two other easy ones as well. The "subscriptionId" is the identifier of the Azure subscription you want to access, and "resourceGroup" is the name of the Resource Group within that subscription holding the SQL servers we are trying to list. You can find both by looking at the resource group in the Azure Portal.

Resource and subscription details in Azure Portal

That leaves us with just four values we need to fill in, which are all related to Active Directory.

  • tenant
  • clientId
  • appKey
  • resource

Creating an Active Directory application

The first thing we need to do is setting up a new application in Azure Active Directory. We need to use the old Azure Management interface to do this. Start by finding your Active Directory.

Azure Active Directory

Then create a new application.

Add new Azure Active Directory application

It's a three step process.

Creating a new Azure Active Directory application

  1. Choose "Add an application my organization is developing"
  2. Choose a name for it
  3. Choose "Web application and/or web api"
  4. Fill in a valid URI (like http://TheNameYouJustChose) in both Sign-on and App ID URI

Configure the app

Sweet, now that we have an application, we just need to configure it properly. All we need to do is grant the application permission to access the "Windows Azure Service Management"-application. So head over to the application configuration and do that.

Configure Azure AD application

At the bottom of the "Configure"-page you can add "permission to other applications". Go ahead and add another application.

Add permission to other applications

Choose the "Windows Azure Service Management"-application.

Choose Windows Azure Service Management

Make sure to select the permission you want to grant as well.

Set permissions

And that's about it! Save the changes and we are ready to start making our code example run!

Fill in the blanks

Everything is set up and ready for us now. Remember the four values needed to get us running?

  • tenant
  • clientId
  • appKey
  • resource
Tenant

Tenant is just the default domain for your Active Directory. You can find that by looking under the "Domains"-page of your Active Directory. In this case it's "clausgeist.onmicrosoft.com".

AD tenant

Client ID

This is the ID of the application you just created, you can find it on the Configuration-page for the app, where we added permissions.

Client ID

App Key

On the very same configuration page you can add an application key by choosing an option in the dropdown, when you save the configuration it will be displayed and you can copy it. You won't be able to see it again later, so copy it right away.

Add application key

Resource

Last but not least we need a "resource" we want to access. In our case the resource is actually the "Azure Service Management App" which is identified by the URI "https://management.core.windows.net/". Go ahead and use "https://management.core.windows.net/" as the value for "resource".

Granting our application permissions

If you fill in the values and try to run the application you will get an error that looks something like this.

AuthorizationFailed: The client '<some-id>' with object id '<some-id>' does not have authorization to perform action 'Microsoft.Sql/servers/read' over scope '<some-scope>'.

That's because our application hasn't been granted permission to actually access our resource group. In order to grant permission we turn to PowerShell.

First, select the subscription you want to access and change mode.

Select-AzureSubscription -SubscriptionId <subscription-id>
Switch-AzureMode -Name AzureResourceManager

Then, assign the Reader-role to your application (identified by the "some-id"-value from the error message we got) on the resource group.

New-AzureRoleAssignment -ObjectId '<some-id>' -ResourceGroupName <resource-group-name> -RoleDefinitionName Reader

If that goes well, you should be all set to run the application and list all the SQL servers within that resource group.

Wrapping up

It took a little time for me to get my head around this and dig up the pieces required to make it work. Hopefully you've found it useful. Either way, it prepares the ground nicely for the blog post I really wanted to write, about the elastic databases preview, which will follow shortly!

View Comments