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:

  1. Create a file named main.bicep
  2. 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!