Windows Azure and scaling: how? (.NET)

Edit on GitHub

One of the key ideas behind cloud computing is the concept of scaling.Talking to customers and cloud enthusiasts, many people seem to be unaware about the fact that there is great opportunity in scaling, even for small applications. In this blog post series, I will talk about the following:

Creating and uploading a management certificate

In order to be able to programmatically (and thus possibly automated) scale your Windows Azure service, one prerequisite exists: a management certificate should be created and uploaded to Windows Azure through the management portal at http://windows.azure.com. Creating a certificate is easy: follow the instructions listed on MSDN. It’s as easy as opening a Visual Studio command prompt and issuing the following command:

1 makecert -sky exchange -r -n "CN=<CertificateName>" -pe -a sha1 -len 2048 -ss My "<CertificateName>.cer"

Too anxious to try this out? Download my certificate files (management.pfx (4.05 kb) and management.cer (1.18 kb)) and feel free to use it (password: phpazure). Beware that it’s not safe to use in production as I just shared this with the world (and you may be sharing your Windows Azure subscription with the world :-)).

Uploading the certificate through the management portal can be done under Hosted Services > Management Certificates.

Management Certificate Windows Azure

Building a small command-line scaling tool

In order to be able to scale automatically, let’s build a small command-line tool. The idea is that you will be able to run the following command on a console to scale to 4 instances:

1 AutoScale.exe "management.cer" "subscription-id0" "service-name" "role-name" "production" 4

Or down to 2 instances:.

1 AutoScale.exe "management.cer" "subscription-id0" "service-name" "role-name" "production" 2

Now let’s get started. First of all, we’ll be needing the Windows Azure service management client API SDK. Since there is no official SDK, you can download a sample at http://archive.msdn.microsoft.com/azurecmdlets. Open the solution, compile it and head for the /bin folder: we’re interested in Microsoft.Samples.WindowsAzure.ServiceManagement.dll.

Next, create a new Console Application in Visual Studio and add a reference to the above assembly. The code for Program.cs will start with the following:

1 class Program 2 { 3 private const string ServiceEndpoint = "https://management.core.windows.net"; 4 5 private static Binding WebHttpBinding() 6 { 7 var binding = new WebHttpBinding(WebHttpSecurityMode.Transport); 8 binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; 9 binding.ReaderQuotas.MaxStringContentLength = 67108864; 10 11 return binding; 12 } 13 14 static void Main(string[] args) 15 { 16 } 17 }

This constant and WebHttpBinding() method will be used by the Service Management client to connect to your Windows Azure subscription’s management API endpoint. The WebHttpBinding() creates a new WCF binding that is configured to use a certificate as the client credential. Just the way Windows Azure likes it.

I’ll skip the command-line parameter parsing. Next interesting thing is the location where a new management client is created:

1 var managementClient = Microsoft.Samples.WindowsAzure.ServiceManagement.ServiceManagementHelper.CreateServiceManagementChannel( 2 WebHttpBinding(), new Uri(ServiceEndpoint), new X509Certificate2(certificateFile));

Afterwards, the deployment details are retrieved. The deployment’s configuration is in there (base64-encoded), so the only thing to do is read that into an XDocument, update the number of instances and store it back:

1 var deployment = managementClient.GetDeploymentBySlot(subscriptionId, serviceName, slot); 2 string configurationXml = ServiceManagementHelper.DecodeFromBase64String(deployment.Configuration); 3 4 var serviceConfiguration = XDocument.Parse(configurationXml); 5 6 serviceConfiguration 7 .Descendants() 8 .Single(d => d.Name.LocalName == "Role" && d.Attributes().Single(a => a.Name.LocalName == "name").Value == roleName) 9 .Elements() 10 .Single(e => e.Name.LocalName == "Instances") 11 .Attributes() 12 .Single(a => a.Name.LocalName == "count").Value = instanceCount; 13 14 var changeConfigurationInput = new ChangeConfigurationInput(); 15 changeConfigurationInput.Configuration = ServiceManagementHelper.EncodeToBase64String(serviceConfiguration.ToString(SaveOptions.DisableFormatting)); 16 17 managementClient.ChangeConfigurationBySlot(subscriptionId, serviceName, slot, changeConfigurationInput);

Here’s the complete Program.cs code:

1 using System; 2 using System.Linq; 3 using System.Security.Cryptography.X509Certificates; 4 using System.ServiceModel; 5 using System.ServiceModel.Channels; 6 using System.Xml.Linq; 7 using Microsoft.Samples.WindowsAzure.ServiceManagement; 8 9 namespace AutoScale 10 { 11 class Program 12 { 13 private const string ServiceEndpoint = "https://management.core.windows.net"; 14 15 private static Binding WebHttpBinding() 16 { 17 var binding = new WebHttpBinding(WebHttpSecurityMode.Transport); 18 binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; 19 binding.ReaderQuotas.MaxStringContentLength = 67108864; 20 21 return binding; 22 } 23 24 static void Main(string[] args) 25 { 26 // Some commercial info :-) 27 Console.WriteLine("AutoScale - (c) 2011 Maarten Balliauw"); 28 Console.WriteLine(""); 29 30 // Quick-and-dirty argument check 31 if (args.Length != 6) 32 { 33 Console.WriteLine("Usage:"); 34 Console.WriteLine(" AutoScale.exe <certificatefile> <subscriptionid> <servicename> <rolename> <slot> <instancecount>"); 35 Console.WriteLine(""); 36 Console.WriteLine("Example:"); 37 Console.WriteLine(" AutoScale.exe mycert.cer 39f53bb4-752f-4b2c-a873-5ed94df029e2 bing Bing.Web production 20"); 38 return; 39 } 40 41 // Save arguments to variables 42 var certificateFile = args[0]; 43 var subscriptionId = args[1]; 44 var serviceName = args[2]; 45 var roleName = args[3]; 46 var slot = args[4]; 47 var instanceCount = args[5]; 48 49 // Do the magic 50 var managementClient = Microsoft.Samples.WindowsAzure.ServiceManagement.ServiceManagementHelper.CreateServiceManagementChannel( 51 WebHttpBinding(), new Uri(ServiceEndpoint), new X509Certificate2(certificateFile)); 52 53 Console.WriteLine("Retrieving current configuration..."); 54 55 var deployment = managementClient.GetDeploymentBySlot(subscriptionId, serviceName, slot); 56 string configurationXml = ServiceManagementHelper.DecodeFromBase64String(deployment.Configuration); 57 58 Console.WriteLine("Updating configuration value..."); 59 60 var serviceConfiguration = XDocument.Parse(configurationXml); 61 62 serviceConfiguration 63 .Descendants() 64 .Single(d => d.Name.LocalName == "Role" && d.Attributes().Single(a => a.Name.LocalName == "name").Value == roleName) 65 .Elements() 66 .Single(e => e.Name.LocalName == "Instances") 67 .Attributes() 68 .Single(a => a.Name.LocalName == "count").Value = instanceCount; 69 70 var changeConfigurationInput = new ChangeConfigurationInput(); 71 changeConfigurationInput.Configuration = ServiceManagementHelper.EncodeToBase64String(serviceConfiguration.ToString(SaveOptions.DisableFormatting)); 72 73 Console.WriteLine("Uploading new configuration..."); 74 75 managementClient.ChangeConfigurationBySlot(subscriptionId, serviceName, slot, changeConfigurationInput); 76 77 Console.WriteLine("Finished."); 78 } 79 } 80 }

Now schedule this (when needed) and enjoy the benefits of scaling your Windows Azure service.

So you’re lazy? Here’s my sample project (AutoScale.zip (26.31 kb)) and the certificates used (management.pfx (4.05 kb) and management.cer (1.18 kb)).

Note: I use the .cer file here because I generated it on my machine. If you are using a certificate created on another machine, a .pfx file and it's key should be used.

This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.

Leave a Comment

avatar

0 responses