If writing Bicep templates feels like setting up IKEA furniture — decorators are the little labels and warnings on the box that help you avoid a build gone wrong 😅
💭 The Scenario
You’re helping the HR department move their app to Azure. To do this the right way, you’re setting up a Bicep template that deploys:
- An App Service Plan (like the server where the app will live)
- An App Service App (the actual HR app that runs on it)
But instead of just typing values willy-nilly, you’re adding rules and helpful hints to guide whoever deploys this in the future.
That’s where decorators come in. Let’s go!
🛠️ Step 1: Build the Template Skeleton
In VS Code:
- Create a file named
main.bicep
- Add this starter code:
param environmentName string = 'dev'
param solutionName string = 'toyhr${uniqueString(resourceGroup().id)}'
param appServicePlanInstanceCount int = 1
param appServicePlanSku object = {
name: 'F1'
tier: 'Free'
}
param location string = 'westus'
var appServicePlanName = '${environmentName}-${solutionName}-plan'
var appServiceAppName = '${environmentName}-${solutionName}-app'
💡 What’s Happening Here?
- You're creating parameters that allow flexibility when deploying.
-
uniqueString()
is like giving your template a fingerprint — it ensures you get a unique name without manually editing anything. - You’re also setting up variables to combine parameters into valid resource names.
🧱 Step 2: Add the Resources
Now let’s tell Azure what to build:
resource appServicePlan 'Microsoft.Web/serverfarms@2024-04-01' = {
name: appServicePlanName
location: location
sku: {
name: appServicePlanSku.name
tier: appServicePlanSku.tier
capacity: appServicePlanInstanceCount
}
}
resource appServiceApp 'Microsoft.Web/sites@2024-04-01' = {
name: appServiceAppName
location: location
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
}
}
So far, so good!
🪄 Step 3: Add Descriptions & Guardrails
Imagine you’re writing this template for your future self (or a teammate). You want to:
- Show a description for each parameter
- Prevent invalid inputs (like someone typing “banana” for an environment name 🍌)
Let’s clean up those parameters:
@description('The name of the environment. This must be dev, test, or prod.')
@allowed([
'dev'
'test'
'prod'
])
param environmentName string = 'dev'
@description('The unique name of the solution. Used to ensure resource names are globally unique.')
@minLength(5)
@maxLength(30)
param solutionName string = 'toyhr${uniqueString(resourceGroup().id)}'
@description('The number of App Service plan instances.')
@minValue(1)
@maxValue(10)
param appServicePlanInstanceCount int = 1
@description('The name and tier of the App Service plan SKU.')
param appServicePlanSku object = {
name: 'F1'
tier: 'Free'
}
@description('The Azure region for deployment.')
param location string = 'westus'
✨ Why Decorators Rock
Think of decorators as:
- Tooltips for anyone using your template
- Seatbelts that stop people from entering bad values
- Training wheels for safe, repeatable deployments
🚀 Step 4: Deploy It to Azure
1. Install & Upgrade Bicep (if needed)
az bicep install && az bicep upgrade
2. Log in
az login
✅ I just hit Enter
because my default subscription was already selected.
3. Create a Resource Group
az group create --name BicepRG --location westus
4. Deploy!
az deployment group create \
--resource-group BicepRG \
--name main \
--template-file main.bicep
Boom. Now you’re deploying a safe, validated, and well-documented infrastructure setup 💪
🧠 In Short: What You Learned
Concept | What It Means |
---|---|
Parameters | Let users customize deployments |
Variables | Reusable values built from parameters |
Decorators | Helpful hints, restrictions, and rules for inputs |
Descriptions | Make the template self-explanatory |
@allowed, @minValue... | Prevent invalid or risky deployments |
✅ Pro Tip: Fixing Common Errors
I got a few errors at first because I accidentally used environment
instead of environmentName
.
If that happens, VS Code will guide you with squiggly lines — and the terminal will be very vocal 😅
Make sure your variable names match exactly, especially if you're doing interpolation like this:
var appServicePlanName = '${environmentName}-${solutionName}-plan'
🏁 Done & Deployed
Head to the Azure Portal, find your BicepRG
resource group, and check:
- ✅ Two resources deployed
- ✅ Your parameters and values under “Inputs”
- ✅ A successful deployment log
You can even click on your App Service App, and if it’s running — open it in the browser to see the welcome page! 🎉
Wanna follow my Azure learning journey?
Stick around — I’m sharing it all, wins and stumbles included 😄
You can find me on LinkedIn — drop me a message and just say hi 👋
Would love to hear what you're working on or learning!