Let's Talk Cloud: Automating VM Deployments with Azure Resource Manager Templates


Hey cloud friends! Welcome back to our "Let's Talk Cloud" series. Today, we're diving into something that can save you tons of time and eliminate those pesky manual errors—automating your VM deployments with Azure Resource Manager (ARM) templates.
If you've been clicking through the Azure portal to create VMs one at a time, you're about to discover a much better way!
Why Automation Matters
Let me start with a quick story. A colleague of mine used to spend hours manually deploying development environments for their team. Every new project meant clicking through dozens of screens, checking countless configuration options, and invariably making small mistakes that would cause problems later. Sound familiar?
When they switched to using ARM templates, what used to take half a day now happens with a single command and finishes in minutes. Plus, every environment is identical—no more "but it works on my machine" headaches!
What Are ARM Templates Anyway?
Azure Resource Manager templates are essentially JSON files that define all the resources you want to deploy to Azure. Think of them as blueprints for your infrastructure. Instead of clicking around in the portal to create resources, you describe what you want in a structured format, and Azure builds it exactly to specification.
The beauty of ARM templates is that they're:
Declarative: You define what you want, not how to create it
Idempotent: Run the same template multiple times and get the same result
Templateable: Use parameters and variables to create reusable templates
Anatomy of an ARM Template
Let's break down what's in a typical template:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": { },
"variables": { },
"resources": [ ],
"outputs": { }
}
Parameters: Values you provide when deploying (like VM size or admin username)
Variables: Values used throughout your template (calculated or constructed)
Resources: The actual Azure resources you're deploying (VMs, networks, etc.)
Outputs: Values returned after deployment (like IP addresses)
Creating Your First VM Template
Let's get practical. Here's what a simple VM deployment template might include:
Virtual Network and Subnet: Every VM needs a network
Public IP Address: For accessing your VM from the internet (optional)
Network Security Group: To control inbound and outbound traffic
Network Interface: Connects your VM to the network
Storage Account: For boot diagnostics
Virtual Machine: The star of the show!
Writing all this from scratch would be tedious, so here are some shortcuts:
Export Template: Deploy a VM manually once, then export the template from the Azure portal
Azure QuickStart Templates: Browse Microsoft's library of pre-built templates on GitHub
Visual Studio Code: Use the Azure Resource Manager Tools extension for template authoring
Parameterizing Your Templates
The real power of ARM templates comes from parameterization. Instead of hardcoding values, you define parameters that can change between deployments.
For a VM deployment, common parameters include:
VM name and size
Admin username and password/SSH key
Operating system image
Network configuration
Disk types and sizes
Here's a quick example of a parameter definition:
"parameters": {
"vmSize": {
"type": "string",
"defaultValue": "Standard_D2s_v3",
"allowedValues": [
"Standard_B2s",
"Standard_D2s_v3",
"Standard_D4s_v3"
],
"metadata": {
"description": "Size of the virtual machine"
}
}
}
You can then reference this parameter later in your template using the parameters()
function:
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
}
Advanced Template Techniques
Once you're comfortable with basic templates, you can explore some advanced techniques:
1. Linked Templates
Break your infrastructure into modular pieces by linking templates together. This is great for complex deployments or reusing common components.
2. Template Functions
ARM templates support a wide range of functions for string manipulation, array operations, resource management, and more. Functions like concat()
, resourceId()
, and copyIndex()
will become your best friends!
3. Copy Elements
Need to deploy multiple identical resources? The copy
element lets you create multiple instances without duplicating code:
"copy": {
"name": "vmCopy",
"count": "[parameters('instanceCount')]"
}
4. Deployment Scripts
Some configuration tasks can't be handled by ARM templates alone. Deployment scripts let you run PowerShell or Bash scripts during deployment to handle these scenarios.
Deploying Your Templates
Once your template is ready, you have several options for deployment:
Azure Portal: Upload and deploy your template through the UI
Azure CLI: Use
az deployment group create
Azure PowerShell: Use
New-AzResourceGroupDeployment
DevOps Pipelines: Integrate with CI/CD for automated deployments
For repeatable deployments, I highly recommend the CI/CD approach—have your templates in source control and automatically deploy them when changes are merged.
Common Gotchas and Tips
Having worked with ARM templates for years, here are some lessons I've learned the hard way:
Test incrementally: Start with a small template and build up
Use validation: Validate your template before deploying (
Test-AzResourceGroupDeployment
)Watch dependencies: Make sure resources are created in the right order
Be careful with secrets: Use Key Vault to handle sensitive information
Set deployment modes: Understand the difference between incremental and complete deployment
What About Bicep?
Before we wrap up, I should mention Bicep—Microsoft's newer language for defining Azure resources. Bicep is essentially a more user-friendly alternative to JSON ARM templates. It's less verbose, supports better tooling, and transpiles to ARM JSON behind the scenes.
If you're just starting with infrastructure as code in Azure, Bicep might be worth exploring. But rest assured, the concepts we've discussed here apply to Bicep as well!
Have you started using ARM templates in your environment? What challenges have you faced? Drop a comment below—I'd love to hear about your experiences!
Until next time, keep automating and stop clicking!
Subscribe to my newsletter
Read articles from Samuel Happiness directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Samuel Happiness
Samuel Happiness
I'm a passionate and innovative software developer, I thrive on crafting elegant solutions that drive real-world impact. With a strong foundation in hands-on experience in mobile and web development, I am adept at turning complex problems into user-friendly applications.