Allocating Static IP Addresses to your VMs

When deploying a workload to Infrastructure services it's always a good idea to define a VNET and deploy your VMs within it. The reason for this is that a VNET is the best way to control the internal address ranges for the VMs in each tier of your application. This is done by defining an address range for your VNET and then defining subnets within the VNET address range. Typically you would define a subnet per tier, so DB, APP and Web.

Now when you create a VM within a VNET, the internal IP address will be allocated as the next available within the range. This gives a certain level of control as you can predict the internal IP addresses. However, this can be troublesome when deploying solutions where you need better control over the IP addresses, for example, SharePoint, Hadoop or MongoDB. If VMs are for some reason stopped and deallocated (and remember we want to build fault tolerance into our systems) then that VM may not be given the same internal IP the next time it starts. The reason for this is that another VM may start and take the next available IP which is that of the one that stopped. Depending on your workload this can cause problems and force you to re-configure your DNS server or other configuration.

So, if we want to do more than predict IP addresses and actually reserve them there is a way to do it using the latest powersehll cmdlets. This cannot be done via the management console so make sure to download the latest cmdlets:

https://www.windowsazure.com/en-us/documentation/articles/install-configure-powershell/

Let's See The Problem

First off I have created a VNET with 2 VMs within a subnet for my DB servers. The subnet defines the 192.168.1.0 /29 address range which means I get 3 IPs

Above you will see that each VM was automatically allocated an internal IP in order based on the range for the subnet. Now I may go ahead and configure my app server to connect to each of these VMs using these IP addresses. But let's stop and de-allocate one of the VMs, DB1. Then we will create a new VM, DB3 and see the internal IP address:

So, we can see that DB3 has now been given the first available address within the range, which is 1.4, the IP that was previously allocated to DB1. If we start Db1 then we can see it has been allocated the next available IP which is 1.6. Now depending on how you design your application or workload this predictability may well be enough.

The Solution

However, if you want the IP addresses to be preserved even after a VM has been de-allocated then there are a number of powershell cmdlets that can help. The primary cmdlet is Set-AzureStaticVNetIP which will allocate a specific internal IP to the VM and this IP will persist post restarts and even de-allocations. Please note: you must use PowerShell, the management portal is not supported. You also must use this command in the context of creating the VM using PowerShell. So trying to run this command against a VM already running will not work. The IP must be assigned and reserved at the time the VM is created.

UPDATE January 2015: You can now assign a reserved IP address to an existing VM

So this time I created the VMs DB1 and DB2 in the same order. This time, as part of creating the VM I allocate a static IP. Here is the script:

I then created DB2 using the same script and just as before stopped and de-allocated the VM, DB1.This time when I create DB3 using the script and allocating a static IP I get a different result than before. This time the next available is not selected (i.e. that of DB1) instead 1.6 is allocated as requested.

 

and now if I restart DB1 I get the 1.4 address previously allocated:

The Conclusion

You can now allocate reserved static internal IP addresses to your VMs which will add an extra level of fault tolerance to your workload if predictable IPs is not an option. Remember you must use the Powershell commands and not the dashboard. I have attached a sample Powershell file you can use as the basis of your testing.

 

 

SetupVMDB1.ps1