Order is everything when setting up SharePoint on Azure IaaS
I spent a bunch of time with my buddy Kirk Evans while at DevConnections in Las Vegas last month, some drinking and watching football, but mostly learning about running SharePoint on Azure. Azure IaaS has come a long way, but is still confusing & troublesome at times. I have written a few PowerShell tools that help me and I will share them in some future posts.
I started playing with SharePoint on Azure IaaS on my own without doing much reading. My goal in this was to see how intuitive it was to get things setup and going for the average person. Once in the console creating a VM was very quick and simple. I was up and running on a pre-built Windows Server image in no time. This was great.
Then I decided that I wanted to build a SharePoint farm. I deployed out 2 addtional VMs. I built an Active Directory and attempted to join the other 2 servers to the domain. This is where I ran into problems.
There are some building blocks that need to first be put in place before you start building servers if you want them to be able to communicate with one another.
The first is the Affinity Group (AG). An AG is required before you can create a Virtual Network. The way that Kirk explained it, the AG is a container to keep your Virtual Network in a single data center. To create an AG you will either use PowerShell or go to Settings at the bottom of the Management Portal and find Affinity Groups as the fourth of five options.
Next create the Virtual Network and assign it ot the AG.
After the Virtual Network is created you will be able to setup a Cloud Service. The Cloud Service is going to be the container for your VMs.
This process sounds uber simple, but the order of things matters here. Now you can create your VMs. Once you have your VMs and your DNS server built you can go in and specify the Domain Controller as a DNS server.
This is where you will hit a snag. In the normal course of events you would be running a domain controller on a static IP address. Unfortunately this is not something that you can do on Azure IaaS. Every time you deprovision a VM, which you have to do unless you want to get charged, your IP address reservation can get taken by another machine.
My solutions to this problem was fairly simple:
1.) Create a virtual network for each of my environments
2.) Always start the VMs in the same order so that they pick up the same IP address each time
The first part was easy, however the second part is difficult when you get beyond one or two people using the same Azure subscription. I needed an easier way to ensure that my VMs would start in a specific order. After a late night with one of my favorite single malts I came up with a fairly simple PowerShell solution.
As a result of my conversations with Kirk, and some annoyance at the inconsistent nature of shutting down VMs using the Management Portal, I decided to look into how I could shutdown my VMs using PowerShell. There is a nice cmdlet for doing this called stop-AzureVM.
Since I want to do this for a set of VMs I needed to be able to run a for-each loop, so I wrote a start and stop function into the script.
I started to use a CSV or text file method for loading the VMs that I wanted to start and stop together when I realized that I didn’t want to have to maintain a series of files on every environment that I create and then distribute that to my team. Not to mention that I have multiple Azure subscriptions that I am using for clients and personal use. The management of that would get cumbersome quickly.
Then I remembered that all of the VMs that I will want to use together are going to be a part of the same Azure Cloud Service (ACS) and that each farm or group of servers that I want to use will have their own unique ACS. There is a cmdlet to get all of the ACS in an Azure Subscription called get-AzureService. I have opted to get the Service Name, Affinity Group, and status of the ACS in my script.
The status field is not overly useful, but if something other than “Created” is returned it is worth investigating since that is the expected value.
Once you have the correct ACS the script will list the VMs that exist within and ask if you want to start or stop them.
The obvious question at this point is “How does this solve the IP address problem that you set out to solve?”
The answer is that the script will always start and stop the VMs in a specific order. Starting the VMs using this script will ensure that the same IP addresses are obtained every time.
The script was originally designed to solve this problem however I have been using it to ensure that my VMs get shutdown cleanly rather than using the Management Portal which, as I mentioned earlier, is inconsiestent at best.
I hope that you find this as useful as I do. I have been using this script since I wrote it Thanksgiving weekend and I stopped tweaking about a week ago. You can find the script here: http://www.jasonhimmelstein.com/scripts/Azure/set-AzureVMs/set-AzureVMs.ps1