DEV Community

1suleyman
1suleyman

Posted on

πŸ’» Exercise 03: Refactoring with Bicep Modules – Making Your Templates Cleaner & Smarter

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
Enter fullscreen mode Exit fullscreen mode

✨ 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Then I created a resource group:

az group create --name BicepRG --location westus
Enter fullscreen mode Exit fullscreen mode

And finally deployed everything:

az deployment group create \
  --resource-group BicepRG \
  --name main \
  --template-file main.bicep \
  --parameters environmentType=nonprod
Enter fullscreen mode Exit fullscreen mode

🧾 Step 4: What Happened in the Portal?

In Azure Portal:

  1. I went to Resource Groups > BicepRG
  2. Clicked the Deployments tab
  3. Saw two entries: main and appService (yes, the module shows up!)
  4. Opened main > Outputs β€” there it was: appServiceAppHostName
  5. 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!

Top comments (0)