Dynamic Azure ARM Template for Server Deployments

Dynamic ARM TemplateEver since I started using Template Deployments I have been perfecting a Dynamic Azure ARM Template for server deployments.  I finally reached a point where I feel this template is complete and am excited to share it with the world.  The code can be found on my GitHub page here.  A brief explications of parameter values are listed below.

First, an Overview

The goal of this ARM template is to deploy a number of servers specified in the parameter file and add to each server a number of data drives, also specified in the parameter file.  The JSON template uses the Copy and CopyIndex() code to create the servers.  This provides looping like functionality to the JSON template, incrementally increasing values such as server name, NIC name, drive names and so on.  I used the term “looping like” because the servers are not created one at a time like traditional looping, they are created in parallel with ARM deployments.  This way, there is little difference in the time it takes to deploy 2 or 8 VM’s.

The last tweak to the ARM template was to set the number of unmanaged data drives in the parameter file and have them created and attached to each server.  This was done by adding another copy command in the virtual machine resource for the data drives.  I struggled with this for a while, but found the solution as part of an Azure quick start template .  The referenced template accomplishes a similar goal as the one I created with some differences in how it’s done.

After the servers are created and data drives attached, Azure Desired State Configuration can be used to group them into one logical drive.  For information on how to do this with Storage Space Direct and Azure DSC, see my post here.

Keep storage limits in mind when using this template.   Be sure the total number of drives does not go beyond a storage accounts drive count, IoPS, or capacity limits.  Information on storage limits can be found here.


And one last note, this template does not configure public IP’s.  My environment has other networking magic in place that negates the need for public IP’s.

Parameters of Interest:

No need to go over the obvious parameters.  Here are some of the more interesting ones:

virtualMachineNamePrefix: This is the name of the VM with the copy index added to the end.  For example, setting the value to “server” and creating three servers will result I server1, server2, server3.

adminPassword: It’s bad form to store passwords in code.  The local admin password is stored in the Key Vault and referenced by the vaults ID.  More information can be found here.

firstIPAddress: This is the IP of the first VM.  The value will increment by one on the last octet for each additional server.

VirtualNetworkDresourceGroup: This assumes the vNet the VM’s are connecting to is in a different resource group.  If not, just add the deployment RG here.

numberOfDataDisks: The number of data disks attached to each server.  Be sure the VM size will support this number and the total number of disks deployed does not exceed any storage account limitations.

domainUsername: The domain account used to join the servers to the domain.

domainPassword: Simular to adminPassword, the Key Vault ID and secretName of the domain join account.

domainJoinOptions: There is limited documentation on this, the value “3” will add the server to the domain

numberOfInstances: The number of VM’s to deploy.  Minimum is set to 2 in the template.

That’s all there is to it.


Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.