Starting with Bicep

Published by Peter KARDA
Category : ARM Template / Azure

When the last year the first alpha version of project Bicep was released, I was a bit skeptical. Another language for the infrastructure? We have already ARM templates and there is already Terraform and there are also some nice projects that enable us to code infrastructure with the common languages (C#, JavaScript, …). So why another DSL language (domain-specific language) to code the Azure infrastructure? Well, sometimes the ARM authoring could be quite laborious mainly when dealing with the large templates. It takes time to find the right place and then modify the right piece of JSON code of the template. As ARM templates are machine-generated JSON files there is just a lot of “noise”  that makes it difficult to understand and modify it. That’s where Bicep brings innovation.


Getting Bicep

The Bicep language was designed to have full parity with the JSON ARM template. It means that everything you can do in Bicep you can do with ARM template and vice versa. Bicep code is transpiled to JSON (if you’re familiar with JavaScript development it’s a bit similar to transpiling TypeScript to JavaScript).

To start the Bicep development it’s recommended to install the Bicep extension for Visual Studio Code.

Bicep VS Code extension

After, when you open a file with .bicep extension the VS Code not only provides the syntax highlighting but also the powerful auto-completion. In one presentation the Bicep development team mentioned that instead of investing the time and resources to the language itself they invested in the tooling development. And truly the Bicep extension works like a charm.


Bicep language

The Bicep language is pretty simple and it’s really easy to start the development. The resource expressed in Bicep is much more compact and readable than JSON template.

Let’s have a simple example of the Azure Storage Account ARM resource expressed side by side as Bicep and as JSON templates.

Bicep vs JSON

As you can see, the Bicep file has only 20 lines while the JSON ARM template has 39. It’s so clear to see what is the resource (storage in our case) and where the parameters and variables are used. The compactness and readability are not the only advantages of Bicep. Among the language features, there are a few that I’d like to mention. Those are the Conditional and Iterative deployment and the Modules.


Conditional deployment

Think about a situation when you need to deploy a server feature but only in the case of deploying to the production environment. In the example below it’s achieved by the conditional deployment. In step (1) we’ve defined the environmentName parameter. (The decorator with allowed values is not required but puts the constraint on the parameter which renders the template safer.) After in step (2) we’ve set a bool variable auditingEnabled that should be set to true only if we deploy to production. Finally, in step (3) we’ll deploy the server auditing settings only in case of production deployment.

Conditional deployment


Iterative deployment

Let’s have another situation. Imagine we’ve deployed Azure API Management and a few APIs. Then we’ve created a Product with a policy that you’d like to assign to all the APIs. This could be simply achieved by iterative deployment. Firstly, (1) define the array of APIs. After the incremental deployment (2) loops through the APIs in the array and deploys for each one the Product.

Iterative deployment



Sometimes we need to break down complex deployments into smaller and more reusable components. The concept of modules allows you to split templates into smaller independent Bicep files/components. Every component can be used in another Bicep solution and as well it could be deployed independently. The modules are replacing the concept of nested and linked templates but in a more manageable way.


Bicep deployment

We can deploy the Bicep file with Azure CLI or Azure PowerShell. They both provide cross-platform tools but I have a slight preference for Azure CLI. Azure CLI from version 2.20.0 or later automatically installs Bicep CLI in case we’re deploying Bicep file. For Azure PowerShell, the Bicep module has to be installed separately. Let’s say we have a Bicep with the definition of all resources for the deployment of the Azure Function App. To deploy the Bicep by using Azure CLI, open console and run the following commands:

az group create --name regdemo --location northeurope

az deployment group create --resource-group regdemo --template-file .\functionapp.bicep --parameters .\functionapp.parameters.json

The first command creates a resource group called regdemo in northeurope region. The second one deploys the Azure Function App in that resource group by using the Bicep file functionapp.bicep. Note that to specify parameters it’s possible to use the same JSON parameter file as used for classic JSON templates.

To integrate the Bicep template with Azure CI/CD pipelines, we need to use the Azure CLI task. The task will execute in InlineScript mode the same Azure CLI commands as were used for Azure CLI deployment in the previous example.


Building and decompilation

As I’ve mentioned at the beginning of the article, there’s a parity between Bicep and JSON templates. The Azure CLI Bicep tooling enables you to build Bicep and decompile the JSON files.

To build/compile Bicep to JSON using the Azure CLI command:

az bicep build –-file main.bicep

It creates main.json file in the same directory as your Bicep file. It might be sometimes a handful to keep the two files in your project mainly if you are in the phase of converting your deployment solution to Bicep.

To decompile JSON to Bicep use the following Azure CLI command:

az bicep decompile --file main.json

It generates main.bicep file. The output is not perfect and you need to correct some generated names to improve readability but it gives you a perfect idea of what the Bicep implementation should be.

You can also try to decompile your Bicep templates directly online in Bicep playground. The site contains as well a large list of sample Bicep templates that could inspire you while working on your Bicep solution.



In my opinion, Bicep is a great way how to do Azure Resource Management. It adds naturally clarity, readability, and modularity to your deployment solution. It’s pleasure to work with VS Code extension and deployment with Azure CLI really embraces the spirit of DevOps – you can deploy your solution from anywhere with simple commands.

If you are interested to learn Bicep then I’d recommend taking the free Microsoft Learn course ‘Deploy and manage resources in Azure by using Bicep‘.