— There’s a Better Way
A Beginner’s Guide to Infrastructure as Code with Azure Bicep
If you’ve been managing your Azure infrastructure by clicking through the portal, you already know the pain: it’s slow, easy to mess up, and nearly impossible to repeat consistently across environments.
There’s a better way — and it’s called Infrastructure as Code (IaC).
Instead of manually configuring resources, you describe your entire infrastructure in a file. Azure reads that file and builds everything for you — consistently, every single time. No more “but it worked in dev” moments.
There are several great tools in the IaC ecosystem to choose from — Terraform, Pulumi, and AWS CloudFormation are all popular options, each with their own strengths. In this post, we’ll be using Microsoft Azure Bicep as our example to walk through the core concepts of IaC. The good news? The fundamental ideas — repeatability, idempotency, version control, environment-based deployments, and pipeline automation — carry across virtually all IaC tools. Once you understand them in Bicep, you’ll feel right at home picking up Terraform or Pulumi.
Let’s also be honest: a lot of infrastructure is still being managed by hand — this is affectionately (and sometimes not so affectionately) known as ClickOps. Someone’s got a tab open in the portal, clicking through wizards and hoping they remember all the settings they changed last time. ClickOps is everywhere, but after reading this post, you’ll have every reason to leave that habit behind for good.
Bicep is Microsoft’s modern language for doing exactly this. It’s clean, readable, and built specifically for Azure. Whether you’re spinning up a single storage account or deploying a full application stack, Bicep gives you full control with a fraction of the effort.
In this guide, we’ll go from zero to your first Bicep deployment — no prior IaC experience needed.
What Is Azure Bicep?
Traditionally, setting up cloud infrastructure meant logging into the Azure Portal and clicking through wizards — creating a virtual network here, a storage account there. It works, but it doesn’t scale.
That’s the problem Infrastructure as Code solves. Instead of clicking, you write code that describes what your infrastructure should look like. Azure reads that code and makes it happen.
With Bicep, your infrastructure becomes consistent, repeatable, and fully transparent. Every setting lives in code — reviewable, version-controlled, and auditable. You can test in a lower environment first before anything touches production, and when you’re ready to deploy, it’s just running a pipeline — no ClickOps required.
Before Bicep, Azure used ARM Templates — JSON files that worked, but JSON doesn’t support comments, making templates hard to read and slow to hand over. Bicep solves this with clean, human-readable syntax that your whole team can follow.
Before Bicep, Azure used ARM Templates — JSON files that worked, but were notoriously verbose and hard to read. Bicep is the modern replacement: same power, far cleaner syntax. Think of it as ARM Templates, but written for humans.
| Capability | Azure Bicep | ClickOps (Portal) |
|---|---|---|
| Repeatability | ✔ Same config, any environment, one command | ✘ Manual steps every time |
| Security controls | ✔ Enforced consistently; reviewable in code | ✘ Easy to miss or misconfigure |
| Version control & audit | ✔ Full history of every change via Git | ✘ No audit trail |
| Rollback | ✔ Revert via source control | ✘ No straightforward path |
| Deployment speed | ✔ Automated pipeline — no manual steps | ✘ Slow portal navigation every time |
| Readability & handover | ✔ Human-readable with comment support | ✘ Relies on tribal knowledge or screenshots |
Prerequisites
Before getting started, make sure you have the following installed and configured:
-
- An Azure account
-
- Azure CLI installed on your machine
For Windows Users:
– Option 1: Open Command Line -> winget install Microsoft.AzureCLI
– Option 2: Download the MSI installer from Microsoft Documentation
For Linux Usres:
– Step 1: curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
– Step 2: Verify installation in Linux: az –version
-
- VS Code with the Bicep extension — gives you syntax highlighting and IntelliSense
Your First Bicep File
A Bicep file is made up of four building blocks:
- Parameters — inputs you can pass in at deploy time (e.g. environment name, location)
- Variables — reusable values computed inside the file
- Resources — the actual Azure resources you want to create
- Outputs — values returned after deployment (e.g. a URL or connection string)
Here’s a simple Bicep file that deploys an Azure Storage Account:
param location string = 'australiaeast'
param storageAccountName string = 'mystorageaccount'
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: storageAccountName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
}
output storageId string = storageAccount.id
Even without any Azure knowledge, you can read this file and understand what it does. That readability is one of Bicep’s biggest strengths.
Deploying with Azure CLI
With your Bicep file ready, it’s time to bring your infrastructure to life using the Azure CLI — a command-line tool that lets you manage Azure resources directly from your terminal.
The steps below walk you through the full deployment process. You start by logging in to your Azure account and pointing the CLI at the right subscription, so your resources land in the correct place. Next, you either create a new resource group — think of it as a folder that organises all your related Azure resources together — or skip that step if you already have one to use.
# Step 1: Log in to Azure
az login
# Step 2: Set your target subscription
az account set --subscription ''
# Step 3: Create a resource group
# (Skip this step if using an existing resource group)
az group create --name --location australiaeast
# Step 4: Deploy the Bicep template
az deployment group create \
--resource-group \
--template-file
What-If: Your Safety Net
The What-If command is your pre-flight check. Before you commit to a deployment, it shows you exactly what Azure is about to create, modify, or delete — without actually doing anything yet.
# Step 1: Log in to Azure
az login
# Step 2: Set your target subscription
az account set --subscription ''
# Step 3: Create a resource group (Skip this step if an existing resource group will be used)
az group create --name --location australiaeast
# Step 4: Test the deployment
az deployment group what-if \
--resource-group
# Step 5: Deploy the Bicep template
az deployment group create \
--resource-group \
--template-file
A typical What-If output looks like this:
Resource and property changes are indicated with these symbols:
+ Create
~ Modify
- Delete
The deployment will make the following changes:
+ Microsoft.Storage/storageAccounts/mystorageaccount
apiVersion: "2022-09-01"
kind: "StorageV2"
location: "australiaeast"
sku.name: "Standard_LRS"
Before committing to the deployment, Step 4 runs a What-If check. This is a dry run that shows you exactly what Azure is about to create, modify, or delete — without actually doing anything yet. It’s a good habit to always review this output before proceeding.
Finally, Step 5 runs the actual deployment. Azure reads your Bicep file, compares it against what currently exists in your resource group, and applies only the necessary changes.
Making Changes to Your Infrastructure
This is where IaC really shines. Need to change your storage account SKU from Standard to Premium? Just update your Bicep file and re-run the deployment.
Think of your Bicep file as a blueprint that describes exactly what your Azure infrastructure should look like. When you run the deployment, Azure reads that blueprint and builds everything to match.
The best part? If you run the same deployment again, Azure won’t blindly create duplicate resources. Instead, it compares the blueprint against what already exists and only makes the necessary changes — this is called idempotency.
This also means your Bicep file becomes the single source of truth for your infrastructure — not someone’s memory, not a wiki page, not a series of portal screenshots.
From a security standpoint, every infrastructure change now goes through source control — giving you a full audit trail, peer-reviewable changes, and security controls that are enforced consistently across every environment. No more hoping someone remembered to tick the right box in the portal.
Where to Go From Here
You’ve covered the fundamentals. Here’s what to explore next as you grow your Bicep skills:
Modules
Break your Bicep files into reusable modules — one file per resource type — and compose them together. This keeps your code clean and DRY as your infrastructure grows.
Parameter Files
Instead of hardcoding values, use .bicepparam files to manage different configurations for dev, staging, and production environments.
CI/CD with Azure DevOps
Automate your deployments by wiring your Bicep templates into an Azure DevOps pipeline. Every merge to main can automatically deploy your infrastructure — no manual CLI steps required.
Infrastructure as Code is one of those skills that feels like a small investment upfront but pays off every single time you deploy. Once you’ve done it this way, going back to clicking through the portal feels unthinkable.