With Windows Azure PowerShell Cmdlets, the process to customize and automate an infrastructure deployment to Windows Azure Infrastructure Services (IaaS) has become a relatively simple and manageable task. This article examines a sample script which automatically deploys seven specified VMs into three target subnets based on a network configuration file with two availability sets and a load-balancer. In several of test runs I have done, the entire deployment took a little more than half an hour.
The developer PowerShell script assumes Windows Azure PowerShell Cmdlets environment has been configured with an intended Windows Azure subscription. A network configuration file is at a specified location.
This file can be created from scratch or exported from Windows Azure NETOWRK workspace by first creating a virtual network. Notice in the netcfg file an affinity group and a DNS server are specified.
The four functions represent the key steps in performing a deployment including building a virtual network, deploying VMs, and configuring availability sets and load-balancers, as applicable.
Within the script, session variables and constants are assigned. The network information needs to be identical with what is defined in netcfg file since they are not automatically populated from an external source at this time.
To deploy multiple VMs programmatically, there is much information repeated. And in some parameters are defined with default values from session variables or the initialization section. When calling a routine, a default value can be overridden by an assigned/passed value.
Since other than the first VM, deploying additional VMs into an existing service does not need to specify the virtual network name. I however employ the same routing with VNetName specified for deploying the first and subsequent VMs into a service, it produces a warning for each VM after the first VM deployed into a service as shown in the user experience later.
Simply passing in an array to the routines and an availability set or a load-balancer will automatically built. These two functions streamline the processes.
Rather than creating a cloud service while deploying a VM, I decided to create individual cloud services first. This makes troubleshooting easier since it is very clear when services are created.
With a target service in place, I simply loop through and deploy VMs based on the names specified in an array. So to deploy or place VMs into an availability set or a load-balancer becomes simply by adding machine names into a target array.
Here, three frontend servers are load-balanced and configured into an availability set.
I kicked off at 3:03 PM and it finished at 3:36 PM with 7 VMs deployed into target subnets including a SharePoint and a SQL servers. The four warnings were due to deploying additional VMs (specifically dc2, sp2013, fe2, and fe3) into their target services while in the function, DeployVMsToAService, I have VNetName specified.
Seven VMs were deployed with specified names.
dc1 and dc2 were placed in the availability set, dcAvSet.
fe1, fe2, and fe3 are placed in the availability set, feAvSet.
The three were load-balanced at feEndpoint as specified in the script.
All VMs were deployed into target subnet as shown in the virtual network, foonet.
The script also produces a log file capturing the states while completing tasks. As a VM is deployed, the associated RDP file is also downloaded into a specified working directory as shown below.
To make the code production ready, more error handling needs to be put in place. The separation of data and program logic is critical here. PowerShell is a very fluid programming tool. If there is a way to run a statement, PowerShell will try to do just that. So knowing how data are referenced and passed in runtime is becoming critical. And by separating data and program logic will noticeably facilitate the testing/troubleshooting process. And the more experience you have scripted and run it with various data, the more you will discover how PowerShell actually behaves which is not necessarily always the same with other scripting language.
A key missing part of the script is the ability to automatically populated the network configuration from or to an external source. Still, the script provides a predictable, consistent, and efficient way to deploy infrastructure with Windows Azure Infrastructure. What must come after is to customize the runtime environment for an intended application, once VMs are in place and followed by installing the application. IaaS puts VMs in place as the foundation for PaaS which provides the runtime for a target application. It is always about the application, never should we forget.