Creating a Virtual Machine Deployment with the Azure Management REST API in a typed way

I’m using the NuGet package (Windows Azure Service Management Library Nuget Package) to communicate with the Azure Management REST API.
I’ve been already writing about the ManagementCertificate class in an earlier post. The parts of this example were already posted, it is just a summary if someone wants to create a VM in the Windows Azure.
You have to create a hosted service with the CreateHostedService method and then call the CreateVmDeployment method for the actual deployment.

using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.Text;
using Microsoft.Samples.WindowsAzure.ServiceManagement;

namespace YourNamespace.Adapter.Azure.ManagementApi
{
    /// <summary>
    /// The Azure REST Api adapter 
    /// </summary>
    public class RestApiAdapter : IRestApiAdapter
    {
        private const string DefaultDeploymentSlot = "Production";
        private const string BlobContainer = "yourstorage.blob.core.windows.net/vhds";
        private const string SourceImageName = "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-201302.01-en.us-30GB.vhd";
        private const string RoleType = "PersistentVMRole";
        private const string DefaultRoleSize = "Small";

        private readonly string _publishSettingsFilePath;
        private readonly ManagementCertificate _managementCertificate;

        /// <summary>
        /// Initializes a new instance of the <see cref="RestApiAdapter"/> class.
        /// </summary>
        public RestApiAdapter()
        {
            // Can get from configuration
            _publishSettingsFilePath = Path.GetFullPath(@"publishsettings file path");
            _managementCertificate = new ManagementCertificate(_publishSettingsFilePath);
        }

        /// <summary>
        /// Gets the subscription id.
        /// </summary>
        private string SubscriptionId
        {
            get { return _managementCertificate.SubscriptionId; }
        }

        /// <summary>
        /// Gets the management certificate.
        /// </summary>
        private ManagementCertificate ManagementCertificate
        {
            get { return _managementCertificate; }
        }

        private IServiceManagement Channel
        {
            get
            {
                return ServiceManagementHelper.CreateServiceManagementChannel("WindowsAzureEndPoint", ManagementCertificate.Certificate);
            }
        }

        /// <summary>
        /// Creates the hosted service.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="azureLocation">The azure location.</param>
        public void CreateHostedService(string name, string azureLocation)
        {
            try
            {
                var createHostedServiceInput = new CreateHostedServiceInput
                    {
                        Label = ServiceManagementHelper.EncodeToBase64String(name),
                        ServiceName = name,
                        Location = azureLocation
                    };

                Channel.CreateHostedService(SubscriptionId, createHostedServiceInput);
            }
            catch (ProtocolException e)
            {
                throw CreateUsableException(e);
            }
        }

        /// <summary>
        /// Creates the vm deployment.
        /// </summary>
        /// <param name="serviceName">Name of the service.</param>
        /// <param name="vmName">Name of the vm.</param>
        /// <param name="password">The password.</param>
        public void CreateVmDeployment(string serviceName, string vmName, string password)
        {
            try
            {
                var vmdeployment = new Deployment
                        {
                            Name = vmName,
                            Label = vmName,
                            DeploymentSlot = DefaultDeploymentSlot,
                            RoleList = new RoleList()
                        };

                var role = new PersistentVMRole
                    {
                        RoleName = vmName,
                        RoleType = RoleType,
                        ConfigurationSets = new BindingList<ConfigurationSet>()
                    };

                var winprovisioningConfigSet = new WindowsProvisioningConfigurationSet
                    {
                        EnableAutomaticUpdates = true,
                        ResetPasswordOnFirstLogon = false,
                        ComputerName = vmName,
                        AdminPassword = password
                    };

                role.ConfigurationSets.Add(winprovisioningConfigSet);

                var networkConfigset = new NetworkConfigurationSet
                    {
                        InputEndpoints = new BindingList<InputEndpoint>
                        {
                            new InputEndpoint { LocalPort = 3389, Name = "RDP", Protocol = "tcp" },
                            new InputEndpoint { LocalPort = 80, Port = 80, Name = "web", Protocol = "tcp" }
                        }
                    };

                role.ConfigurationSets.Add(networkConfigset);

                role.DataVirtualHardDisks = new BindingList<DataVirtualHardDisk>
                {
                    new DataVirtualHardDisk
                        {
                            HostCaching = "ReadWrite",
                            DiskLabel = "CacheDisk",
                            LogicalDiskSizeInGB = 50,
                            MediaLink = GetVhdUri(BlobContainer, serviceName, vmName, true)
                        }
                };

                role.Label = ServiceManagementHelper.EncodeToBase64String(vmName);
                role.RoleSize = DefaultRoleSize;
                role.OSVirtualHardDisk = new OSVirtualHardDisk
                {
                    MediaLink = GetVhdUri(BlobContainer, serviceName, vmName),
                    SourceImageName = SourceImageName
                };
                vmdeployment.RoleList.Add(role);

                Channel.CreateDeployment(SubscriptionId, serviceName, vmdeployment);
            }
            catch (ProtocolException e)
            {
                throw CreateUsableException(e);
            }
        }

        private static Uri GetVhdUri(string blobcontainerAddress, string serviceName, string vmName, bool cacheDisk = false, bool https = false)
        {
            var now = DateTime.UtcNow;
            string dateString = now.Year + "-" + now.Month + "-" + now.Day;

            var address = string.Format("http{0}://{1}/{2}-{3}{4}-{5}-650.vhd", https ? "s" : string.Empty, blobcontainerAddress, serviceName, vmName, cacheDisk ? "-CacheDisk" : string.Empty, dateString);
            return new Uri(address);
        }

        private static Exception CreateUsableException(ProtocolException protocolException)
        {
            var webException = protocolException.InnerException as WebException;
            if (webException != null && webException.Response != null)
            {
                var responseStream = webException.Response.GetResponseStream() as MemoryStream;
                if (responseStream != null)
                {
                    var responseBytes = responseStream.ToArray();
                    var responseString = Encoding.UTF8.GetString(responseBytes);
                    return new Exception(responseString);
                }
            }

            return new Exception("No return message could be extracted from the exception!");
        }
    }
}
Advertisements

About Tamas Nemeth

Husband and proud father of two daughters in Nürnberg. I'm working as a Senior Software Developer and an enthusiastic Clean-Coder. I spend most of my free time with my family (playing, hiking, etc...). I also play table-tennis and badminton sometimes...
This entry was posted in Technical Interest and tagged , , , , , , , , . Bookmark the permalink.

3 Responses to Creating a Virtual Machine Deployment with the Azure Management REST API in a typed way

  1. Hari says:

    Hi Nemeth,

    Thanks for the wonderful article. I am getting “400 Bad request” error, when i call management API and couldn’t able to figure out “why”. Please help me…………

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s