Exploring Azure Bicep

Recently I have been exploring Azure Bicep and the benefits it provides. Azure Bicep is a Domain Specific Language that allows the rapid creation of ARM Templates, in an easier manner.

I’ve previously found ARM templates challenging, especially with the complexity that can arrive with deployment at scale. Bicep aims to improve this, providing a simpler way of authoring templates, with additional benefits like dependency resolution, and flexibility in where we declare parameters, variables, and resources.

Getting Started:

To install Bicep, use the PowerShell below:

# Create the install folder
$installPath = "$env:USERPROFILE\.bicep"
$installDir = New-Item -ItemType Directory -Path $installPath -Force
$installDir.Attributes += 'Hidden'
# Fetch the latest Bicep CLI binary
(New-Object Net.WebClient).DownloadFile("https://github.com/Azure/bicep/releases/latest/download/bicep-win-x64.exe", "$installPath\bicep.exe")
# Add bicep to your PATH
$currentPath = (Get-Item -path "HKCU:\Environment" ).GetValue('Path', '', 'DoNotExpandEnvironmentNames')
if (-not $currentPath.Contains("%USERPROFILE%\.bicep")) { setx PATH ($currentPath + ";%USERPROFILE%\.bicep") }
if (-not $env:path.Contains($installPath)) { $env:path += ";$installPath" }
# Verify you can now access the 'bicep' command.
bicep --help
# Done!

A full installation guide, including other platforms, is available here. It is also a good idea to install the VS Code extension:

The extension validates that our code is authored correctly – further details are available on the extension page here.

Goals of Azure Bicep:

The below goals are from the Azure Bicep GitHub Page:

  1. Build the best possible language for describing, validating, and deploying infrastructure to Azure.
  2. The language should provide a transparent abstraction for the underlying platform. There must be no “onboarding step” to enable it to a new resource type and/or apiVersion in Bicep.
  3. Code should be easy to understand at a glance and straightforward to learn, regardless of your experience with other programming languages.
  4. Users should be given a lot of freedom to modularize and reuse their code. Reusing code should not require any ‘copy/paste’.
  5. Tooling should provide a high level of resource discoverability and validation, and should be developed alongside the compiler rather than added at the end.
  6. Users should have a high level of confidence that their code is ‘syntactically valid’ before deploying.

For me – point 3 is the key feature. I have struggled along with ARM templates before, and found myself drawn to Terraform as an alternative (because I find it easier to author and understand). Bicep is very helpful for making code easy to understand and learn.

Why Bicep Helps:

Below is a summary of the goals of Azure Bicep – as you can see, it is designed to make our lives easier! 🙂

  • Simpler Syntax (compared to JSON).
  • Simple string interpolation.
  • Simpler resource declaration.
  • Direct resource property access.
  • Modules – allowing us to break a project into multiple files.
  • Flexible declaration.
  • Automatic dependency mapping.
  • Richer validation (when compared to ARM).

Getting Started? Try Bicep Playground!

The Bicep Playground is a great place to get started and understand Bicep and how it works. It also provides a way to visually understand how Bicep can help – and comes right back to Point 3 above… it simplifies the authoring of ARM templates. Using a specific example from the Playground, below I am using the Simple Windows VM template. As you’ll see below – there are significant differences between the Bicep and ARM templates. (Click the images to expand).

For the images below – Bicep is on the left, and the ARM template is on the right:

Below I have highlighted a few of the differences – so you can see how Bicep simplifies things:


We can use variables in Bicep as shown below. 

Resource Creation using Variables:

When creating resources, you can see the simplification that Bicep allows – creating the resource we need and using our variables is really easy.

Dependency Mapping:

This is also automated in Bicep – if there is a dependency on another resource being in place, Bicep will automatically create this for you.


Outputs are much more simple in Bicep too:

Working with Bicep

Working with Bicep is really really easy! Bicep files can be authored in an application like VS Code, and when the Bicep file is ready for deployment, the following command should be run:

bicep build .\azuredeploy.bicep

This will build the Bicep file – and the output of this is a JSON file, which we can then deploy in the usual way. See the example below – I am using the Private DNS Zone template from the Bicep Playground. Below, all I have is my Azure Bicep file:

When ready to build, we run the following command:

bicep build ./azuredeploy.bicep

This then creates a JSON file within our project directory:

We can now deploy the JSON in our usual way!

Want to keep exploring? – Check out these Links: