This is an ongoing series on Windows Azure.  The series starts here, and all code is located on GitHub: https://github.com/mmooney/MMDB.AzureSample.  GitHub commit checkpoints are referenced throughout the posts.

(Yes, I know that Microsoft has recently renamed Windows Azure to Microsoft Azure, but hey, I’m in the middle of a series here, and consistency is important.  In my humble opinion, nobody cares whether it’s called Windows Azure or Microsoft Azure or Metro Azure or Clippy Azure.  I’ll try to stick to just “Azure” though.)

So I’m getting back to this series after a little while (ok, a year).  I’ve spent a lot of the last year building out the Sriracha Deployment System, and open source package management and deployment system.  It’s coming along very nicely with a lot of cool features, and the beta users so far love it.  Anyhow, as a part of that I wanted to have a nice clean way to deploy a Cloud Service to Azure (mostly for selfish reasons to simplify deployments of SportsCommander).

In the last post in this series, we covered a way to automated deployments via PowerShell.  That definitely works pretty well, but it requires installing the Azure Cmdlets, and muddling around with PowerShell, which lots of folks (including me) would rather not deal with.

So what are our other options?

Azure Management REST APIs

So it turns out Azure has a bunch of really nice, logical, easy to use, well documented REST APIs.  You GET/POST to a URL, sometimes with an XML file, and get an XML file back.

But that is still a lot of work, and seems like it should be a solved problem.  You have to deal with a lot of endpoints for a simple deployment.  You need to deal with UTF encoding, URL encoding, XML schemas, error handling, and a whole bunch of blah blah blah that just seems unnecessary.

What I really wanted was a nice clean library that let me call a few functions to carry out the common steps that I and a hundred other developers want to do every day.

Wait, aren’t their already libraries for this?

Sure, there are some.  The main one is the official Windows Azure Management Libraries.  These are an add-on library that the Azure team made to work the Azure REST APIs from C#, which certainly sounds exactly like what I was looking for.  Any it very well may be, but I couldn’t get it to work. When I would call into it, it would hang indefinitely even though I know that the underlying HTTP call had completed, and I think has something to do with how it’s using the fancy new async/await stuff, and there is a deadlock somewhere.  I tried pulling the source code and building it, but it’s using a whole bunch of multitargeting stuff; I needed .NET 4.0 versions, and they were building as 4.5 by default.  Anyhow, I pouring WAAAY too much time into something that was supposed to make my life easier. 

And there are certainly other libraries as well, but they seemed to take a Swiss Army knife approach, trying to solve everyone’s probably in every situation, which means that they a little to complicated to use for my task.

Frankly, all I really to do is call some URLs and work with some XML.  My tolerance for complexity for something like that is VERY low.

Let’s reinvent that wheel as a better mousetrap

When in doubt, assume anything not invented here is junk and write it from scratch, right?  So I created a library for this which was exactly what I was looking for, and hopefully you’ll find it useful as well.

 

The code is located on GitHub at https://github.com/mmooney/MMDB.Azure, and on NuGet at https://www.nuget.org/packages/MMDB.Azure.Management.  The GitHub readme has a good intro and some sample code, but I’ll get into some more detail here.

Authentication

Before you get started you’ll need an Azure account.  If you don’t have one, some charming fellow wrote up a walkthrough on how to do it.

Once you have an account, you’ll need some authentication information to connect to the REST APIs.  Azure uses the idea of Management Certificates authorize the management calls, which gives you a lot of flexibility to issue access to different individual individuals and applications.  It also comes in handy when you accidentally check your management certificate into GitHub and need to revoke it.

Now if you Google around for how to create a mangement certificate, you’ll see a whole bunch of stuff about makecert.exe and local certificate stores and thumbprints and X.509 certificates and plenty of detailed information that will scare off a lot of developers that just wanted deploy some code and are wondering why this is so hard in the first place.

So here’s the easy way (which was covered in the last post as well):

  • Install the Azure PowerShell Cmdlets on any machine, and it doesn’t need to be your deployment machine.  This is just to get the management certificate.
  • If you have not yet, open PowerShell in Administrator mode and run the following command, also know as “Make-PowerShell-Useful”:
    Set-ExecutionPolicy RemoteSigned
  • And then run this command in PowerShell (doesn’t need to be Admin mode), which will launch up a browser, prompt you to log into Azure, and then download a Azure Publish Settings file:
Set-ExecutionPolicy RemoteSigned

And you’ll get something that looks like this:

<?xml version="1.0" encoding="utf-8"?>
<PublishData>
  <PublishProfile
    PublishMethod="AzureServiceManagementAPI"
    Url="https://management.core.windows.net/"
    ManagementCertificate="[Redacted]">
    <Subscription
      Id="[Redacted]"
      Name="3-Month Free Trial" />
  </PublishProfile>
</PublishData>

 

And that my friends, is your Azure Subscription Identifier and Management Certificate.  Grab those values, you’ll need them in a second.

Enter MMDB.Azure.Management

So I put together a simple library that does a bulk of what you may need to do for deploying an Azure Cloud Service.  The goal was abstract away all of the unnecessary noise around XML and schema namespaces and versions Base-64 encoding, and provide a nice and easy for creating, get, updating, and deleting Cloud Services, Storage Accounts, Deployments, and blob files.

First, install the NuGet Package:

PM> Install-Package MMDB.Azure.Management

 

Then, create an AzureClient object, passing in your subscription identifier and management certificate:

string subscriptionIdentifier = "FromYourPublishSettingsFile";
string managementCertificate = "AlsoFromYourPublishSettingsFile";
var client = new AzureClient(subscriptionIdentifier, managementCertificate);

 

Then you can do lots of fun stuff like creating a Cloud Service (and checking that the name is actually available first, of course):

string serviceName = "MyNewServiceName";
string message;
bool nameIsAvailable = client.CheckCloudServiceNameAvailability(serviceName, out message);
if(!nameIsAvailable)
{
    throw new Exception("Cannot create " + serviceName + ", service name is not available!  Details" + message);
}

var service = client.CreateCloudService(serviceName);

Console.WriteLine("Successfully created service " + serviceName  + "!  URL = " + service.Url);

 

Or creating a Storage Account (again, making sure that the name is available first):

string storageAccountName = "MyNewStorageAccount";

string message;
bool nameIsAvailable = client.CheckStorageAccountNameAvailability(storageAccountName, out message)
if(!nameIsAvailable)
{
    throw new Exception("Cannot create " + storageAccountName + ", service name is not available!  Details" + message);
}

var storageAccount = client.CreateCloudService(storageAccountName);

//Initial setup is complete, but it is still resolving DNS, etc
Console.WriteLine("Initial creation for storage account " + storageAccountName + " complete!  URL = " + storageAccount.Url);

//Wait for the entire setup to be complete
client.WaitForStorageAccountStatus(storageAccountName, StorageServiceProperties.EnumStorageServiceStatus.Created, timeout:TimeSpan.FromMinutes(2));
Console.WriteLine("Final setup " + storageAccountName + ", your storage account is ready to go");

 

Now, actually deploying something can take a few steps, like creating a Cloud Service, creating a Storage Account, waiting for everything to get initialized, getting the storage keys for the newly created Storage Account, uploading the Azure package file as a blob to the Storage Account, and then telling Azure to use that blob to create the Cloud Service.  Oh, and then wait for everything to actually initialize (yes, this can take a while on Azure, especially if you have a lot of instances).

string serviceName = "MyNewServiceName";
var service = client.CreateCloudService(serviceName);

string storageAccountName = "MyNewStorageAccount";
var storageAccount = client.CreateStorageAccount(storageAccountName);
client.WaitForStorageAccountStatus(storageAccountName, StorageServiceProperties.EnumStorageServiceStatus.Created);

string azureContainerName = "MyDeploymentContainer";
string azurePackageFile = "C:\\Build\\MyAzurePackage.cspkg";
string azureConfigFile = "C:\\Build\\MyAzureConfig.cscfg";
string azureConfigData = File.ReadAllText(azureConfigFile);
string deploymentSlot = "staging";

var storageKeys = client.GetStorageAccountKeys(storageAccountName);
var blobUrl = client.UploadBlobFile(storageAccountName, storageKeys.Primary, azurePackageFile, azureContainerName);

var deployment = client.CreateCloudServiceDeployment(serviceName, blobUrl, azureConfigData, deploymentSlot);
client.WaitForCloudServiceDeploymentStatus(serviceName, deploymentSlot, DeploymentItem.EnumDeploymentItemStatus.Running, TimeSpan.FromMinutes(5));
client.WaitForAllCloudServiceInstanceStatus(serviceName, deploymentSlot, RoleInstance.EnumInstanceStatus.ReadyRole, TimeSpan.FromMinutes(10));
 

 

See it in action

Again there are a basic usage examples over at the readme, and there are some more exhaustive examples in the test project

You can also see it in real-live action over in the DeployCloudService task in Sriracha.Deploy source.  There you can see how it handles a lot of the day-to-day stuff like checking whether the Cloud Service and Storage Accounts already exist, creating vs. upgrading deployments, etc.

Running the tests

The first time you try to run the test project, you will get some errors that “Azure.publishsettings.private” does not exist.  Get a copy of a publish settings file (see the Authentication section above), and drop it in the root of the MMDB.Azure.Management.Tests folder, and rename it to “Azure.publishsettings.private”, and you should be good to go.  You shouldn’t have to worry about accidentally committing this file, because .private files are excluded in the .gitignore, but make sure to keep an eye on it just to be safe.

The end

So hopefully you find this usual.  If so, let me know on Twitter (@mooneydev).  Obviously this doesn’t cover every single thing you’d want to do with Azure, and I’m sure we’ll be building more features as they are needed.  If you need something you don’t see here, create an issue over on GitHub, or better yet, take a crack at implementing and send over a pull request.  I tried to make the code really approachable and easy to work with, so it shouldn’t be too hard to get started with it and add some value.

3 thoughts on “Windows Azure 5: Deploying via C# using MMDB.Azure.Management

  1. Pingback: blog.atwork.at | Automation von Azure-Teil 3

  2. Pingback: Automation von Azure-Teil 3

  3. Pingback: Windows Azure 6: Deploying via Sriracha Command Line Tools « The Mooney Project

Leave a reply

required

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>