📦 Day 3: Understanding ARM Templates & Infrastructure as Code (IaC)

Welcome to Day 3 of the Azure Zero to Hero series!
Today’s focus is on Infrastructure as Code (IaC) in Azure using ARM Templates.

You’ll learn:

  • What is IaC?

  • Why ARM Templates matter in Azure

  • The structure of an ARM template

  • How to deploy one from the CLI

  • Real-world use case with a simple example


🧠 What is Infrastructure as Code (IaC)?

Infrastructure as Code (IaC) is the practice of defining your cloud infrastructure using code or configuration files, rather than clicking through GUIs.

With IaC, you can:

  • Automate deployments

  • Version control your infrastructure

  • Reuse templates

  • Ensure consistency across environments (Dev → Test → Prod)


💬 ARM Template: What and Why?

ARM = Azure Resource Manager
ARM Templates are JSON files that define the infrastructure and configuration for your Azure solution.

Think of it as a blueprint — define once, deploy many times.

✅ Benefits:

  • Declarative syntax

  • Repeatable deployments

  • Supports complex dependency management

  • Native Azure support

  • Integrates with Azure DevOps, GitHub Actions, etc.


📐 ARM Template Structure

Here’s what a basic ARM template looks like:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "vmName": {
      "type": "string",
      "defaultValue": "myarmvm"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2022-11-01",
      "name": "[parameters('vmName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "hardwareProfile": {
          "vmSize": "Standard_B1s"
        },
        ...
      }
    }
  ]
}

🧪 Step-by-Step: Deploy an ARM Template

📁 1. Create a simple ARM template

Save the below file as vm-template.json:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "vmName": {
      "type": "string",
      "defaultValue": "vmfromtemplate"
    },
    "adminUsername": {
      "type": "string"
    },
    "adminPassword": {
      "type": "securestring"
    }
  },
  "resources": [
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2022-11-01",
      "name": "[parameters('vmName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "hardwareProfile": {
          "vmSize": "Standard_B1s"
        },
        "osProfile": {
          "computerName": "[parameters('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "Canonical",
            "offer": "UbuntuServer",
            "sku": "20_04-lts",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "FromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('vmName'),'-nic'))]"
            }
          ]
        }
      }
    }
  ]
}

🧪 2. Deploy the template using Azure CLI

Create a resource group:

az group create --name arm-demo-rg --location eastus

Deploy the template:

az deployment group create \
  --name vm-deployment \
  --resource-group arm-demo-rg \
  --template-file vm-template.json \
  --parameters adminUsername=azureuser adminPassword=MyP@ssw0rd123

✅ Your VM and all supporting resources will be created as defined in the JSON template.


🧾 Best Practices with ARM Templates

PracticeWhy it Matters
Use parameter filesTo separate configuration from code
Use linked templatesFor modularization and reusability
Store templates in source controlEnables versioning and collaboration
Validate templates before deploymentCatch issues early

🧠 ARM vs Bicep vs Terraform (Quick Comparison)

FeatureARM TemplateBicepTerraform
LanguageJSONBicep (DSL)HCL (HashiCorp)
ComplexityHigh (verbose)Low (simplified)Medium
Native to Azure❌ (uses provider)
ReusabilityManual effort

👉 We’ll explore Bicep in a future post for cleaner, ARM-compatible IaC.


✅ Summary

StepTask
1️⃣Learned what ARM templates are
2️⃣Created a JSON template
3️⃣Deployed it using Azure CLI
4️⃣Understood ARM vs Bicep vs Terraform

🔜 Coming Up: Day 4 – Using Azure Bicep: The Future of ARM Templates

We’ll learn how Bicep simplifies ARM deployments with a cleaner syntax, modular structure, and developer-friendly tooling.


💬 Need help writing your own ARM templates? Drop a question in the comments!
📌 Follow for more updates in the Azure Zero to Hero journey.

0
Subscribe to my newsletter

Read articles from SRINIVAS TIRUNAHARI directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

SRINIVAS TIRUNAHARI
SRINIVAS TIRUNAHARI