Wanna keep your infrastructure as code tidy and future-friendly? Say hello to Bicep modules — the human friendly version of ARM templates 😄
🎯 What This Post is About
In this hands-on exercise, I took my existing Bicep template and broke it up using modules — little reusable building blocks that keep your main file clean and organized.
Here’s what I learned:
- 📦 How to extract App Service-related stuff into its own reusable module
- 🎯 How to pass parameters into that module (like location, name, and environment)
- 🧾 How to return values (outputs) from the module back to the main deployment
- ✅ How to test and verify it all using the Azure CLI and the Azure Portal
🛠️ What’s a Bicep Module?
Think of your main Bicep file like the director of a movie — it calls the shots. A module is like a supporting actor: focused, self-contained, and easy to reuse in other projects. Instead of putting everything in one script, you give roles to individual modules and tell them when to perform.
📁 Step 1: Creating the Module File
First, I created a folder called modules
and a file inside it called appService.bicep
. Then I moved all the App Service logic there.
Here's what it looks like:
param location string
param appServiceAppName string
@allowed([
'nonprod'
'prod'
])
param environmentType string
var appServicePlanName = 'toy-product-launch-plan'
var appServicePlanSkuName = (environmentType == 'prod') ? 'P2v3' : 'F1'
resource appServicePlan 'Microsoft.Web/serverfarms@2024-04-01' = {
name: appServicePlanName
location: location
sku: {
name: appServicePlanSkuName
}
}
resource appServiceApp 'Microsoft.Web/sites@2024-04-01' = {
name: appServiceAppName
location: location
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
}
}
output appServiceAppHostName string = appServiceApp.properties.defaultHostName
✨ Why this is cool:
- The module is self-contained. It knows everything it needs to deploy App Services.
- We can reuse this module in other projects without touching the rest of our infrastructure.
🧹 Step 2: Cleaning Up the Main File
I went into my main.bicep
and:
- Removed the App Service resources and variables
- Kept the parameters (since the module still needs them)
Then I added this near the bottom:
module appService 'modules/appService.bicep' = {
name: 'appService'
params: {
location: location
appServiceAppName: appServiceAppName
environmentType: environmentType
}
}
output appServiceAppHostName string = appService.outputs.appServiceAppHostName
So now the main file stays focused, and all the heavy lifting is handled inside the module.
🧪 Step 3: Time to Deploy!
I logged into Azure CLI:
az login
Then I created a resource group:
az group create --name BicepRG --location westus
And finally deployed everything:
az deployment group create \
--resource-group BicepRG \
--name main \
--template-file main.bicep \
--parameters environmentType=nonprod
🧾 Step 4: What Happened in the Portal?
In Azure Portal:
- I went to Resource Groups > BicepRG
- Clicked the Deployments tab
- Saw two entries:
main
andappService
(yes, the module shows up!) - Opened main > Outputs — there it was:
appServiceAppHostName
- Copied the hostname, pasted it in a browser, and 💥 saw the default App Service welcome page!
🧠 In Short: Why Bicep Modules Are Worth It
Concept | What I Gained |
---|---|
Modules | Cleaner, reusable code |
Parameters | Flexible inputs passed from parent template |
Outputs | Values exposed from module to parent |
Separation of Concerns | Clear boundaries between responsibilities |
Reusability | Use the same logic in multiple environments/projects |
🔚 Final Thoughts
Bicep modules reminded me of organizing your closet: instead of stuffing all your clothes into one drawer, you put shirts in one section, pants in another, socks somewhere else — then label it all! 🧦👕
This exercise helped me appreciate structure and scalability when it comes to managing cloud infrastructure.
🚀 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!