Gaurav Mantri's Personal Blog.

A New Version Of Windows Azure Service Management API Is Available with Delete Specific Role Instances and More Goodies

Yesterday, while answering a question on Stack Overflow I came to know about the availability of some new features in Windows Azure Service Management API. This blog post will summarize some of those changes and will show some code to perform these new operations.

Version Number

As you know, each release of Service Management API has a unique version number and in order to use the features available in that version you must specify that version number in “x-ms-version” request header. The version number for this release (which includes all the cool new features) is “2013-08-01”.

Now that we have talked about the version number, let’s talk about the features.

Delete Role Instances

IMHO, this is one of the coolest and useful feature included in this release. In short, this operation allow you to specify the role instances you wish to remove from your cloud deployment. Earlier you didn’t have the control over which instances you want to remove but now you do. So, more power to you :), which is always good. You can read more about this feature here: http://msdn.microsoft.com/en-us/library/windowsazure/dn469418.aspx.

There are some scenarios where this feature is super useful:

  • You can use this option to intelligently scale down. Earlier scaling down would mean changing the “instance count” in your service configuration file and then perform “Change Deployment Configuration” operation. While this is perfectly fine however I see two issues with this approach:
    • This is an error prone operation and you may end up making changes which you didn’t intend to make. This may create a havoc with your service.
    • When you perform this operation, it is applied to all roles in your service and for a short amount of time your role instances will go down to apply these changes.

    image
    Picture above shows the status of my service immediately when I was trying to scale down my instance count. As you can see all of my services are in “RunningTransitioning” mode.  However when you use “Delete Role Instances” operation, you know exactly which instances you want to take down and only those instances will be taken off of your deployment. All other instances and other services are not impacted at all. While scaling down, you can simply check which instances are not being used (using Windows Azure Diagnostics or other measures) and you remove those instances while scaling down.

  • Sometimes you just want to remove an instance which is not working properly. This feature would allow you to accomplish that.

If you need more reasons, do read this blog post from Richard: http://coderead.wordpress.com/2013/10/28/deleting-instances-on-azure-cloud-services/

One important thing: You can’t delete all role instances in your role using this operation.

Sample Code:

Here’s the sample code to accomplish this. In this example, I’m trying to remove two instances from the production deployment of my cloud service.

        static void DeleteRoleInstance(string[] roleInstanceNames)
        {
            string endpoint = string.Format("https://management.core.windows.net/{0}/services/hostedservices/{1}/deploymentslots/production/roleinstances/?comp=delete", subscriptionId, cloudServiceName);
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(endpoint);
            req.ClientCertificates.Add(cert);//cert is the X509Certificate2 object representing management certificate
            req.ContentType = "application/xml";
            req.Headers.Add("x-ms-version", "2013-08-01");
            req.Method = "POST";
            string requestBodyFormat = @"<RoleInstances xmlns=""http://schemas.microsoft.com/windowsazure"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"">{0}</RoleInstances>";
            StringBuilder sb = new StringBuilder();
            foreach (var roleInstance in roleInstanceNames)
            {
                sb.AppendFormat("<Name>{0}</Name>", roleInstance);
            }
            var requestBody = Encoding.UTF8.GetBytes(string.Format(requestBodyFormat, sb.ToString()));
            using (var stream = req.GetRequestStream())
            {
                stream.Write(requestBody, 0, requestBody.Length);
            }
            try
            {
                using (var resp = req.GetResponse())
                {
                    using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
                    {
                        var responseData = sr.ReadToEnd();
                        Console.WriteLine(responseData);
                    }
                }
            }
            catch (WebException webEx)
            {
                using (var resp = webEx.Response)
                {
                    using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
                    {
                        var errorDetails = sr.ReadToEnd();
                        Console.WriteLine(errorDetails);
                    }
                }
            }
        }

List Subscription User Accounts

Ever wondered who all have management access to your subscription? Well you could always visit Windows Azure Portal to find that information but why go there when you can do it right from a console app (or PowerShell or whatever) without going through the portal. This can be accomplished by performing this operation. You can read more about this feature here: http://msdn.microsoft.com/en-us/library/windowsazure/dn469420.aspx.

Sample Code:

        public class SubscriptionPrincipal
        {
            public string Role { get; set; }
            public string Email { get; set; }
        }

        static void ListSubscriptionPrincipals()
        {
            string endpoint = string.Format("https://management.core.windows.net/{0}/principals", subscriptionId);
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(endpoint);
            req.ClientCertificates.Add(cert);//cert is the X509Certificate2 object representing management certificate
            req.Headers.Add("x-ms-version", "2013-08-01");
            req.Method = "GET";
            try
            {
                using (var resp = req.GetResponse())
                {
                    using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
                    {
                        var responseData = sr.ReadToEnd();
                        var xe = XElement.Parse(responseData);
                        var subscriptionPrincipals = new List<SubscriptionPrincipal>();
                        foreach (var elem in xe.Elements(XName.Get("Principal", "http://schemas.microsoft.com/windowsazure")))
                        {
                            var subscriptionPrincipal = new SubscriptionPrincipal()
                            {
                                Role = elem.Element(XName.Get("Role", "http://schemas.microsoft.com/windowsazure")).Value,
                                Email = elem.Element(XName.Get("Email", "http://schemas.microsoft.com/windowsazure")).Value,
                            };
                            subscriptionPrincipals.Add(subscriptionPrincipal);
                        }
                        var format = "Email = {0} | Role = {1}";
                        foreach (var subscriptionPrincipal in subscriptionPrincipals)
                        {
                            Console.WriteLine(format, subscriptionPrincipal.Email, subscriptionPrincipal.Role);
                        }
                    }
                }
            }
            catch (WebException webEx)
            {
                using (var resp = webEx.Response)
                {
                    using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
                    {
                        var errorDetails = sr.ReadToEnd();
                        Console.WriteLine(errorDetails);
                    }
                }
            }
        }

image

List Role Sizes

As the name suggests, this operation list the role sizes that are available under your subscription. You can read more about this feature here: http://msdn.microsoft.com/en-us/library/windowsazure/dn469422.aspx.

Sample Code:

        public class RoleSize
        {
            public string Name { get; set; }
            public string Label { get; set; }
            public int Cores { get; set; }
            public int MemoryInMb { get; set; }
            public bool SupportedByWebWorkerRoles { get; set; }
            public bool SupportedByVirtualMachines { get; set; }
        }

        static void ListRoleSizes()
        {
            string endpoint = string.Format("https://management.core.windows.net/{0}/rolesizes", subscriptionId);
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(endpoint);
            req.ClientCertificates.Add(cert);//cert is the X509Certificate2 object representing management certificate
            req.Headers.Add("x-ms-version", "2013-08-01");
            req.Method = "GET";
            try
            {
                using (var resp = req.GetResponse())
                {
                    using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
                    {
                        var responseData = sr.ReadToEnd();
                        var xe = XElement.Parse(responseData);
                        var roleSizes = new List<RoleSize>();
                        foreach (var elem in xe.Elements(XName.Get("RoleSize", "http://schemas.microsoft.com/windowsazure")))
                        {
                            var roleSize = new RoleSize()
                            {
                                Name = elem.Element(XName.Get("Name", "http://schemas.microsoft.com/windowsazure")).Value,
                                Label = elem.Element(XName.Get("Label", "http://schemas.microsoft.com/windowsazure")).Value,
                                Cores = Convert.ToInt32(elem.Element(XName.Get("Cores", "http://schemas.microsoft.com/windowsazure")).Value),
                                MemoryInMb = Convert.ToInt32(elem.Element(XName.Get("MemoryInMb", "http://schemas.microsoft.com/windowsazure")).Value),
                                SupportedByWebWorkerRoles = Convert.ToBoolean(elem.Element(XName.Get("SupportedByWebWorkerRoles", "http://schemas.microsoft.com/windowsazure")).Value),
                                SupportedByVirtualMachines = Convert.ToBoolean(elem.Element(XName.Get("SupportedByVirtualMachines", "http://schemas.microsoft.com/windowsazure")).Value),
                            };
                            roleSizes.Add(roleSize);
                        }
                        var format = "Name = {0} | Label = {1} | Cores = {2} | MemoryInMb = {3} | SupportedByWebWorkerRoles = {4} | SupportedByVirtualMachines = {5}";
                        foreach (var roleSize in roleSizes)
                        {
                            Console.WriteLine(string.Format(format, roleSize.Name, roleSize.Label, roleSize.Cores, roleSize.MemoryInMb, roleSize.SupportedByWebWorkerRoles, roleSize.SupportedByVirtualMachines));
                        }
                        //Console.WriteLine(responseData);
                    }
                }
            }
            catch (WebException webEx)
            {
                using (var resp = webEx.Response)
                {
                    using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
                    {
                        var errorDetails = sr.ReadToEnd();
                        Console.WriteLine(errorDetails);
                    }
                }
            }
        }

image

Summary

Pretty interesting new features. Right??? My personal favorite is obviously “Delete Role Instances”. Let’s hope more new features are announced which will empower us developers. As always, if you find any issues with the post please let me know and I will fix them ASAP. Please feel free to share your thoughts by providing comments below.

Happy Coding!!!


[This is the latest product I'm working on]