A Software engineer with a tangent on DevOps/SRE and all things cloud - from the dark world of WinTel. Loves to play around with CI/CD tools, and all things cloud scale, and spends much of his time gaming. If you're a Ops/Infra/WinTel guy looking to transform into something more relevant, this is your blog!
nic.json - nothing special, contains a NIC Azure RM resource
nsg-ad.json - nothing special, contains an NSG Azure RM resource with inbound/outbound rules for a domain controller
sharedresources.json - contains the following resources:
Storage Account(s) - straight resource deployment
Public IP Address - straight resource deployment
Vnet - linked deployment to vnnet.json. See the code snippet above to see how template linking works. Had to define a variable to point to the JSON template link hosted in github.
vnet.json - contains the following resources:
VNET resource - straight up VNET resource deployment with aggregate subnet resources
Network Security Group - linked deployment to deploy nsg-ad.json bound to the subnets. Another example of linked deployment usage.
vnet-with-dns.json - same as vnet.json, only with DNS server addresses included in the subnet definitions (see below). This is required so the proper AD DNS server address is plugged in to the VNET after proper DC promotion.
Now, this is where the cool stuff happens. As this covers alot of magic, this deserves a special section, with in-depth code block analysis.
The VMFactory JSON Template
I wont cover the parameters in detail, but to put some more context on how variable generation works, ill cover the minimum. Parameters are pretty straight forward, and you should get an understanding of what parameters are required once you see the variables and the resources section.
You can see below the parameter vmRole:
The vmRole parameter is basically what tells the VMFactory what type of VM it is. By feeding this to the template, it will automatically pick up the VM Role configurations defined in the property bags. Which leads us to the next section.
Variables Section - The VMFactory property bags, dynamic variable generation
The first code block shows the general purpose variables such as osDiskname, dataDiskName etc. - which are dynamically generated by concatenating the vmName parameter, and the suffix “OSDisk.vhd”.
These variables make sure that all VHD URIs are unique. Variables such as VNET ID and Subnet ID are also indicated here.
Lastly, but most importantly, we have the variable vmDynamicRole. This is the key cog in all of this - which concatenates the string “vmRole” and the parameter vmRole.
What is this for, you may ask? Well, take a look:
Let’s say, the Parameter vmRole has a value of AADC. (Which stands for Azure AD Connect)
“vmRole” + “AADC” = vmRoleAADC.
Still not seeing it? Well take a look at the next code block.
Here we have complex objects. Recommended reading, JSON complex objects/schema
Remember the scenario a while ago? “vmRole” + “AADC” = vmRoleAADC?
Do you see the complex object below named vmRoleAADC? Along with the child objects it has such as vmSize, osDiskURI, dataDiskURI etc.?
By now, it should start making sense.
In our scenario, the variable vmDynamicRole will take the value of the complex object vmRoleAADC.
Which means, using an ARM variable reference
Allows us to dynamically get the value for vmSize of the given vmRole.
For vmRoleAADC, should yield the value Standard_A2.
Let that sink in a bit, and let’s head to the section where the VMs are actually created.
Resource Section - How to access property bags
In the code block below, we have the actual AzureRM Virtual Machine resource.
Can you see how the vmDynamicRole variable is accessed?
And how it’s child objects such as imagePublisher, imageOffer, imageSKU, osDiskURI are referenced?
Also, take a look at the DSC resource here:
What? DSC? Don’t worry, we’ll cover how DSC works here on another post.
Also take a look at the “protectedSettings” section. This basically makes sure that no credentials are sent in plain text. Just make sure that the DSC
That’s alot to take in - but you may ask, why go through the trouble of architecting a complex way to create VMs?
Well, all in the line of re-usability, configuration management & code readability. This fixed config approach also allows you to keep the configurations of Vm types sacred while giving you freedom to define VM instances as you will.
In an actual production environment, you would have the armtemplates scripts secured by a more stringent change management process, while the armdeploy templates will be a bit more lax.