Hey folks! In this lab, I took my basic ARM template (the one that just created a storage account) and turned it into something way more flexible and useful. Think of this like leveling up from “just clicking buttons in the portal” to automating infrastructure that’s reusable and dynamic.
Let me show you what I did — and more importantly, why it matters.
🎯 The Goal (in plain English)
Imagine you're baking cookies. You don’t want to hardcode “2 cups of sugar” into every recipe — sometimes you want less sugar, or chocolate chips instead of raisins. Same thing here.
I wanted my ARM template (aka my infrastructure recipe) to:
- Take inputs (like storage account name and type)
- Use only approved types (no weird or unsupported configurations)
- Output the result — like “Here’s your new storage account URL!”
This way, I can reuse the same template for different apps, regions, and scenarios without rewriting everything from scratch.
🛠 What I Used
- Visual Studio Code with the ARM Tools extension
- Azure CLI
- My own Azure subscription
- A keyboard, some endurance, and trial & error 💻
🧪 Step 1: Adding Parameters (Giving My Template a Brain)
I updated the top of my template to accept two parameters — think of them like fill-in-the-blank fields:
-
storageName
: This is the name of the storage account (it has to be globally unique). -
storageSKU
: This controls how durable and performant the storage is (like choosing between regular mail or FedEx).
"parameters": {
"storageName": {
"type": "string",
"minLength": 3,
"maxLength": 24,
"metadata": {
"description": "The name of the Azure storage resource"
}
},
"storageSKU": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS",
"Standard_ZRS",
"Premium_LRS",
"Premium_ZRS",
"Standard_GZRS",
"Standard_RAGZRS"
],
"metadata": {
"description": "Allowed values for Azure Storage SKUs"
}
}
}
✅ Why this matters: I can now deploy this template again and again — just by changing the input values. Like filling out a form instead of rewriting the whole document.
🧪 Step 2: Using the Parameters (Actually Applying the Inputs)
In the part of the template where the storage account is created, I updated it to plug in the values from my parameters:
"name": "[parameters('storageName')]",
"sku": {
"name": "[parameters('storageSKU')]"
}
I also added a little “tag” called displayName
so when I look at the resource later in the portal, I can quickly see what name was used:
"tags": {
"displayName": "[parameters('storageName')]"
}
🧠 Real-life analogy: This is like making a name tag at a conference — it doesn’t change what you do, but it helps people identify you easily.
🧪 Step 3: Adding Outputs (Showing Results After It’s Deployed)
After deploying the storage account, I wanted to pull out its URL automatically — so I could pass it to a dev, app, or another script.
Here’s what I added at the end of the template:
"outputs": {
"storageEndpoint": {
"type": "object",
"value": "[reference(parameters('storageName')).primaryEndpoints]"
}
}
✅ This means once the template runs, it hands back info like:
- Blob endpoint
- Queue endpoint
- File endpoint
Kind of like saying: “Okay, your storage account is ready — here’s the address!”
⚙️ Final Template Summary
Here’s what my finished template looks like (shortened for clarity):
{
"parameters": {
"storageName": { ... },
"storageSKU": { ... }
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[parameters('storageName')]",
"sku": {
"name": "[parameters('storageSKU')]"
},
"tags": {
"displayName": "[parameters('storageName')]"
},
...
}
],
"outputs": {
"storageEndpoint": {
"value": "[reference(parameters('storageName')).primaryEndpoints]"
}
}
}
🚀 Deployment Time (Putting it to Work)
From the terminal, I ran:
az deployment group create \
--resource-group RG1 \
--name deploy-storage-$(date +'%d-%b-%Y') \
--template-file azuredeploy.json \
--parameters storageName=mystoragecool123 storageSKU=Standard_GRS
And boom — my storage account showed up in Azure with the exact name and SKU I provided, along with the output showing where to find it.
🔍 Bonus: I Also Tested What Happens When It Fails
I tried using an invalid SKU like "Basic"
and got this lovely error:
"The provided value for the template parameter 'storageSKU' is not valid."
✅ That’s good! It means my template is smart enough to reject bad input — like trying to order something that’s out of stock.
🧠 Key Lessons (That I’d Tell a Friend or Teammate)
💡 Skill | 🧠 Real-World Explanation |
---|---|
Parameters | Like fill-in-the-blanks — you make your template reusable. |
Allowed Values | Like a dropdown menu — you limit choices to what's valid. |
Outputs | Like a receipt — shows what got created and where to find it. |
Error Handling | Templates fail fast if you give them the wrong ingredients. |
Tagging | Makes it easy to label and find stuff later in the Azure Portal. |
🧹 Clean-Up
After testing, I cleaned everything up to avoid charges:
az group delete --name RG1
🙋♂️ Final Thoughts
I used to think ARM templates were scary walls of JSON, but now I see them more like custom Lego instructions — you tell Azure what pieces you want and where to put them. And with parameters and outputs, you can make those instructions work for any set, not just one.
🚀 Stay tuned for more as I continue my learning journey with Azure!