SQL Server with Mr. Denny

Dec 23 2019   4:00PM GMT

Dynamically Assigning an Availability Set to a VM in an ARM Template

Denny Cherry Denny Cherry Profile: Denny Cherry

Tags:

Recently I was creating an ARM template for a client.  The idea for the ARM template was that we were going to create two VMs, and it would also create an Availability Set and assign the VMs to the Availability Set.  So that’s no problem.Cloudflare being the cloud

We then got a request to also create an ARM template for one VM without the Availability Set.  I didn’t want to create (and then have to manage) a second template. I wanted one template.  So I added a parameter to the ARM template called “SingleMachineInstall” which accepted “Yes” no “No” to the parameters section like this.

“SingleMachineInstall”: {
“type”: “string”,
“allowedValues”: [ “Yes”, “No” ],
“defaultValue”: “No”,
“metadata”: {
“description”: “Check this if this should be installed as a single VM. This will prevent the ILB, Availability Set and the second VM from being created.”
}
},

For all the objects that I didn’t want to create when this parameter had a value of “Yes” I simply added a condition statement to each object like this.

“condition”: “[equals(parameters(‘SingleMachineInstall’), ‘No’)]”,

Then came the complex part of this.  When there are two VMs being created, each VM needed to be dependent on the Availability Set. But when there’s only one VM, I’m not creating the Availability Set, so if the dependency is still there, the deployment will fail.  One thing that I found in my testing, is that you can set a resource to be dependant on the same resource multiple times.  So what I did in the dependsOn section of the VM template, I combined this with an IF statement. In the IF statement, I put down that if the Parameter is set to “No” then we pass in the resourceId for the Availability Set. if the Parameter is set for “Yes” then we pass in the NIC again, which makes the dependsOn succeed either way.

“dependsOn”: [
“[concat(parameters(‘VM1_Name’), ‘_nic0’)]”,
“[if(equals(parameters(‘SingleMachineInstall’), ‘No’), resourceId(‘Microsoft.Network/loadBalancers’, parameters(‘AvailabilitySet_Name’)), concat(parameters(‘VM1_Name’), ‘_nic0’))]”
],

The final thing that we needed to figure out was the properties.availabilitySet value within the Virtual Machine configuration.  The problem with this value is that it expects to have a sub-Id called id like this.

“availabilitySet”: {
“id”: “[resourceId(‘Microsoft.Compute/availabilitySets’, parameters(‘AvailabilitySet_Name’))]”
},

Now, this couldn’t be wrapped in a simple IF statement, because then the id that is being passed in, is a blank string, which throws an error message.

There’s another syntax for this parameter which came in really handy for this.  That syntax is to pass in the ID, without specifying that it is an id like is shown here.

“availabilitySet”: “[resourceId(‘Microsoft.Compute/availabilitySets’, parameters(‘AvailabilitySet_Name’))]”,

Now, this syntax is important to us because we can use this to help us not put in an Availability Set if the parameter is set to not create the Availability Set.

We create one additional thing to make this work, first we create a variable within the ARM template.  I called this variable “availabilitySet”.  Because of the way ARM works, no error will be thrown if there’s no Availability Set created.

“availabilitySet”: {
“id”: “[resourceId(‘Microsoft.Compute/availabilitySets’, parameters(‘AvailabilitySet_Name’))]”
}

Back within the VM section of the ARM template, we need to tell the ARM template to use the variable if it needs, and if it isn’t needed we send is a NULL value.  This way if we need an Availability Set, we specify the child value, otherwise, we pass in nothing.

“availabilitySet”: “[if(equals(parameters(‘SingleMachineInstall’), ‘No’), variables(‘availabilitySet’), json(‘null’))]”,

When I was able to do this, I was using “apiVersion”: “2019-03-01” so this may not work in later version of the API, so be warned about that.

When I was searching around on Google I couldn’t find any examples that showed how to do this. They may be out there, but I couldn’t find them.

Hopefully, this technique works for you in the few places that you need this sort of technique.

Denny

1  Comment on this Post

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.
  • pashaliski
    Thanks, good article
    20 pointsBadges:
    report

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: