“Wait... you want to deploy this thing not once, not twice, but in every region we’re launching?”

Me: "Say less." 😄


🚀 What’s This Exercise About?

You’ve probably deployed a single SQL database or resource using Bicep. But what happens when your app — like our smart teddy bear project — is expanding globally?

Instead of copy-pasting the same code for each region, we let Bicep loops do the heavy lifting. Think of it like cloning your whole setup for different cities with just one instruction.


🎯 The Mission

Here’s what we’re going to do:

  • Turn our existing SQL Server + DB setup into a reusable module
  • Use a loop in Bicep to deploy it to multiple regions
  • Redeploy with a new region later, just by changing one line 🔥

🏗️ Step 1: Turn Your SQL Setup into a Module

We already had a main.bicep file that deployed:

  • SQL Server
  • SQL Database
  • Optional auditing (only if environment is Production)

Now we break that out into its own file so it can be reused.

✅ Create a folder called modules

✅ Move main.bicep inside it

✅ Rename it to: database.bicep

Boom 💥 Now database.bicep is a self-contained recipe for one deployment.


✨ Step 2: Create a New main.bicep to Loop It

In the root of your folder, create a new main.bicep file.

Start with this:

@description('The Azure regions to deploy to.')
param locations array = [
  'westus'
  'eastus2'
]

@secure()
@description('SQL admin login')
param sqlServerAdministratorLogin string

@secure()
@description('SQL admin password')
param sqlServerAdministratorLoginPassword string

Now the cool part — use a loop to call the module multiple times:

module databases 'modules/database.bicep' = [for location in locations: {
  name: 'database-${location}'
  params: {
    location: location
    sqlServerAdministratorLogin: sqlServerAdministratorLogin
    sqlServerAdministratorLoginPassword: sqlServerAdministratorLoginPassword
  }
}]

This loop is like saying:

“Hey Bicep, deploy database.bicep once for each location in my list.”

No extra copy-pasting. No headaches.


🧾 What’s Inside database.bicep?

It’s still your original code — just with parameters passed in:

@description('Region to deploy')
param location string

@secure()
param sqlServerAdministratorLogin string

@secure()
param sqlServerAdministratorLoginPassword string

@description('SQL SKU')
param sqlDatabaseSku object = {
  name: 'Standard'
  tier: 'Standard'
}

@description('Environment type')
@allowed(['Development', 'Production'])
param environmentName string = 'Development'

@description('Storage account SKU')
param auditStorageAccountSkuName string = 'Standard_LRS'

var sqlServerName = 'teddy${location}${uniqueString(resourceGroup().id)}'
var sqlDatabaseName = 'TeddyBear'
var auditingEnabled = environmentName == 'Production'
var auditStorageAccountName = take('bearaudit${location}${uniqueString(resourceGroup().id)}', 24)

...and of course the resource definitions for SQL Server, DB, auditing, and storage (with if conditions where needed).


⚙️ Step 3: Deploy to Azure!

First, make sure everything’s ready:

az bicep install && az bicep upgrade
az login
az group create --name BicepRG --location westus

Then run the deployment:

az deployment group create \
  --resource-group BicepRG \
  --name main \
  --template-file main.bicep

You’ll be asked to enter the SQL admin login and password. Use the same one across all regions to keep things clean.

☑️ Wait for it to finish, then…


🔍 Step 4: Check It Out in the Portal

Head to the Azure Portal:

  • Go to Resource Groups > BicepRG
  • You should see resources in:
    • West US
    • East US 2

Nice and tidy — two full deployments in one go!


🌏 Step 5: Add East Asia & Redeploy

Let’s say the teddy bear team is ready to launch in Asia. No problem.

Open main.bicep and update the parameter:

param locations array = [
  'westus'
  'eastus2'
  'eastasia' // 👈 New location
]

Save and run again:

az deployment group create \
  --resource-group BicepRG \
  --name main \
  --template-file main.bicep

Bicep compares what’s deployed, sees that East Asia is new, and adds just that.

Back in the portal, hit Refresh — boom, there’s your East Asia deployment ✨


🧠 In Short

What We Did Why It’s Cool 🚀
Moved Bicep logic to a module Reusable, clean, and organized
Used loops to deploy by region Scalable deployments — no code duplication
Redeployed with 1 new region Zero stress updates — just change a list

💡 Final Thoughts

Bicep loops are your best friend when deploying to multiple regions. Whether you’re building for dev/test/prod or launching globally like our teddy bear project 🧸 — using loops and modules together keeps your code flexible, reusable, and future-proof.


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!