Migrating to Azure Bicep

IntermediateTopic20 min5 min readAzure

AZ-104 notes: Migrating to Azure Bicep. Covers key concepts for the Azure Administrator Associate exam.

  • Structured Summary + Deep Technical Understanding

Primary technologies involved:

  • Azure Bicep
  • Azure Resource Manager
  • Azure Cloud Shell

Official Documentation:

Bicep CLI reference:

Decompile ARM to Bicep:

Deploy Bicep with Azure CLI:

Deploy Bicep with PowerShell:

1️⃣ Big Picture: Why Migrate from ARM to Bicep?

We already know:

ARM JSON → Talks to Azure Resource Manager → Talks to Resource Providers → Deploys resources

Bicep is:

✔ A higher-level language ✔ Easier to read and write ✔ Fully compatible with ARM ✔ Automatically compiled into ARM JSON

So migration = converting existing ARM templates into cleaner Bicep files.

2️⃣ Key Tool: Azure Bicep CLI

Inside Cloud Shell (Bash):

  • az bicep help

Important commands:

  • These two commands enable full round-trip conversion.

3️⃣ Bicep → ARM (Build Command)

Command used:

  • az bicep build --file deploy.bicep --outfile test.json

What happens:

  • deploy.bicep → Compiled → test.json (ARM template generated)
  • This JSON file is exactly what Azure uses during deployment.

Important:

  • ✔ This happens automatically during normal Bicep deployment ✔ You can run it manually for inspection/debugging

4️⃣ Inspecting the Generated ARM Template

The generated JSON includes:

  • $schema
  • contentVersion
  • parameters
  • variables
  • resources

Example components seen:

  • ✔ Location parameter with default ✔ WebAppName parameter ✔ SKU variable ✔ LinuxFxVersion variable ✔ Microsoft.Web/serverfarms resource ✔ Microsoft.Web/sites resource

This confirms:

  • Bicep preserves full ARM template structure.

5️⃣ ARM → Bicep (Decompile Command)

Command used:

  • az bicep decompile --file test.json

Output:

  • test.bicep

Important warning displayed:

  • ⚠ "Best effort decompilation"

Meaning:

  • Complex templates may not convert perfectly
  • Manual cleanup/refactoring may be needed
  • Especially true for advanced nested templates
  • Docs explicitly state decompilation is not guaranteed to be 100% clean.

6️⃣ Why Decompilation Might Need Refactoring

Possible issues in complex templates:

  • Nested deployments
  • Linked templates
  • Copy loops
  • Advanced conditions
  • Expressions rewritten awkwardly
  • Redundant variables

After decompile:

  • ✔ Always review file ✔ Simplify expressions ✔ Replace hardcoded values with parameters ✔ Improve readability

7️⃣ Full Migration Workflow (From Demo)

  • Step 1 — Start with Bicep Step 2 — Build → JSON Step 3 — Decompile JSON → Bicep Step 4 — Deploy new Bicep file

Deployment command used:

  • az deployment group create \
  • --name DemoDeployment \
  • --resource-group $rgName \
  • --template-file test.bicep

This proves:

  • ✔ Decompilation result is fully deployable ✔ Round-trip conversion works

8️⃣ Verifying Deployment

Command used:

  • az resource list --resource-group $rgName --output table

Result showed:

  • ✔ App Service Plan ✔ Web App ✔ Cloud Shell storage account

Deployment state:

  • ProvisioningState = Succeeded

9️⃣ What This Demonstrates Architecturally

  • Bicep is NOT a separate deployment engine.

It always becomes:

  • Bicep → ARM JSON → Azure Resource Manager → Resource Providers → Resources
  • Even decompiled Bicep will go through ARM when deployed.

🔟 When Should You Migrate?

You should migrate ARM to Bicep if:

✔ Templates are large and hard to maintain ✔ Teams struggle with JSON readability ✔ You want modular architecture ✔ You want easier parameter management ✔ You want better developer experience

1️⃣1️⃣ Enterprise Migration Strategy

Real-world approach:

  • Export existing ARM templates
  • Decompile to Bicep

Refactor Bicep:

  • Extract modules
  • Simplify parameters
  • Improve naming
  • Store in Git
  • Integrate into CI/CD
  • Retire legacy ARM JSON

1️⃣2️⃣ Advanced Migration Tips

✔ Use Modules

Break large templates into reusable modules:

  • module webApp './webapp.bicep' = {
  • name: 'webAppDeployment'
  • params: {
  • ...
  • }
  • }

✔ Replace Hardcoded Values

Convert:

  • name: 'mywebapp'

Into:

  • param webAppName string
  • name: webAppName

✔ Use Secure Parameters

@secure()

param adminPassword string

1️⃣3️⃣ Migration Caveats

Always test in dev before production rollout.

1️⃣4️⃣ Bicep CLI Build vs Deploy

Important distinction:

Build

Only compiles Bicep → JSON No resources deployed

Deploy

  • Compiles AND deploys

Example deploy via CLI:

  • az deployment group create \
  • --resource-group myRG \
  • --template-file main.bicep
  • No need to manually build first.

1️⃣5️⃣ Mental Model

Think of migration like this:

  • ARM JSON = Assembly language Bicep = C#
  • Decompile = reverse-engineering assembly back into C#
  • It works, but it may need cleanup.

1️⃣6️⃣ Key Exam Points

✔ Bicep build converts to ARM JSON ✔ Bicep decompile converts JSON to Bicep ✔ Decompile is best-effort only ✔ Bicep fully supports all ARM features ✔ Deployment scopes include resource group, subscription, management group ✔ Underlying engine is always Azure Resource Manager

1️⃣7️⃣ Final Takeaways

  • ✔ Migrating to Bicep improves maintainability ✔ Bicep is production-ready (GA) ✔ ARM knowledge is still required ✔ Decompile helps accelerate migration ✔ Always review converted templates ✔ Round-trip conversion works ✔ Azure still deploys using ARM internally

If you'd like next:

  • 🏗 Full real-world ARM → Bicep refactor example
  • 🔄 Large nested ARM template migration walkthrough
  • 🚀 CI/CD pipeline deploying Bicep with GitHub Actions
  • 📘 40 exam-style ARM & Bicep migration questions
  • 🧠 Advanced Bicep modules and architecture patterns
  • Tell me your goal level (exam, architect, DevOps, or enterprise).

More in Microsoft Azure