IaC with Azure Bicep – Part1

Introduction to Azure Bicep

This post begins a series on Infrastructure as Code (IaC) with Microsoft Bicep. This is the successor – or more precisely, the extension – of the classic ARM templates for Azure. Anyone who has already gained experience with this knows where it could sometimes hurt, especially in terms of readability and dependencies. With numerous optimizations, the Bicep approach tries to remedy this. Bicep is also declarative and a domain-specific language (DSL).

We first clarify basic aspects of the IaC pattern and briefly classify the different options for Azure in comparison. Then it’s time to get down to the nitty-gritty: How does the local development environment have to be set up, what is the basic structure of Bicep and how can the templates or their resources be provisioned.

Later in the series, we’ll also look at advanced techniques for code dynamization and modularization options for pipeline reuse and automation.

General aspects of IaC

No matter what technology: why Infrastructure as Code?

Infrastructure as Code (IaC) is an approach that has a significant impact on the management of resources in the Azure cloud or other hyperscalers. There are several ways to create, configure, and remove these resources, including using a graphical user interface (GUI) such as the Azure Portal, native command-line tools such as Azure CLI, PowerShell modules, or various SDKs for C#, Java, and Python. Ultimately, however, all actions are performed by the Azure Resource Manager, the central API. If, as in the examples given, no IaC is used, it usually takes significantly more requests to the API and the correct sequence must be followed manually for the most part – with IaC, most of the work is done by the resource manager, as shown as following:

Fig. 1: Comparison of Bicep IaC and imperative CodeI[1]

The use of the GUI is clear, but in critical production environments this can be problematic. For example, the question may arise as to who created a resource, whether the original configuration has been changed, and whether it is still valid and meets the specified standards. Repetition of deployments and the accidental deletion or misconfiguration of resources can also lead to problems. While Azure Logs and Policies are helpful tools, they definitely don’t answer all questions in the context and don’t prevent configurations from drifting apart.

IaC is essential for a stable cloud environment. Instead of manually creating resources in the portal, code is written and stored in a repository, from where it is typically deployed. An unintentional deviation from the target and actual state can thus be avoided.

The advantages of IaC are obvious: the procedure offers traceability, versioning, enables teamwork and easy deployment in different stages. In addition, deployments can be automated and repeated. The desired configuration of the Azure services is recorded in the code and is compared with the current state. This means that it does not matter how often a deployment is initiated – there is no need for complicated queries to existing resources to avoid errors. In many projects, it is even prescribed to provide cloud resources only via IaC, whereby the portal is usually only available to certain users for quick troubleshooting.

Azure IaC – Bicep, ARM or Terraform – which approach fits?

There are basically several options for IaC, the focus of this series of articles is on the Azure native variant Bicep. Another option would be Terraform, which takes a cross-cloud provider approach. However, it comes with some complexity and has created some uncertainty with the recent changes in the licensing model.

The first approach to Azure native IaC development was the Azure Resource Manager (ARM) templates. These are JSON-based files in which the resources and parameters to be created are defined and can then be processed by the Resource Manager. Compared to Bicep or Terraform, however, they require significantly more lines of code and the correct definition of dependencies can be complicated.

But spoiler alert: ARM templates will remain – which is mainly related to the way Bicep, the latest variant of Azure’s IaC development, works. Bicep provides specific syntax, keywords, and functions that can be used to develop the code. However, this is “only” a wrapper for the already known ARM functions. For resource deployment, ARM templates are ultimately generated by the runtime and communicated with the resource manager. This is compatible in both directions, all Bicep code can be displayed in ARM templates and vice versa. ARM templates can also often be found under the hood of the services, for example in Azure Policies or in the template generation for configuration changes of an Azure Data Factory.

The benefits of Bicep

In the end, of course, it depends on many factors which IaC approach is pursued. Compared to Terraform, it can be safely stated that Bicep for Azure is the in-house variant, i.e. developments and updates find their way here first, even if the time gap is shorter than before. Tight integration and compatibility with Azure services are logical goals of the developments. In addition, Bicep falls under Microsoft’s support umbrella, although it is a free service. Bicep also dispenses with external statefile handling, as is known from Terraform and causes one or the other complication.

Compared to traditional ARM templates, the significantly increased readability due to much shorter code and the simpler representation of dependencies between resources are particularly noteworthy. This makes the code more error-resistant, cleaner, and more readable.

Like Terraform, Bicep supports better module management compared to ARM templates, which increases reusability and consistency in the code. Likewise, the tools for code development are usually more advanced and mature, for example the various available VS Code Extensions.

If you are not active in the multi-cloud or provider environment and need a uniform approach for the development teams, you are generally very well advised to use Azure deployments with Bicep.

Background of the Bicep development

The story of Bicep begins with the blueprints. With this approach, for example, tries to create packages for new subscriptions with resources, policies, and RBAC assignments to simplify and speed up onboarding. The product team had various challenges in the implementation and many of them were related to the technology of the ARM templates. It became clear in the process that some updates were needed in the implementation and that these are sometimes very difficult for use in blueprints due to the ARM structure and functionality. Although blueprints themselves are likely to disappear in the future, Bicep owes its existence to the process of developing the service. There were then various approaches to simplifying IaC in Azure. The considerations ranged from a PowerShell-based wrapper to improvements in JSON processing to a completely new development with runtime. The new development was rejected due to the necessary effort and compatibility with existing – still widely used – ARM-based environments. In the end, Bicep prevailed based on the TypeScript – Javascript model. Also on board was Anders Hejlsberg – inventor of Turbo Pascal and with deep footprints on VBA, the .Net Framework and TypeScript – to support the design of the language.

Despite all the advantages of Bicep, the ARM-first approach applies, i.e. improvements will always find their way there first. The adaptation of Bicep is to take place organically and without coercion, neither for customers nor product teams such as the Data Factory. Even though Bicep was not listed as production-ready for quite a while, it was never in danger of a possible project cancellation. The background information from this section could be obtained in an interview with the Product Manager from the Bicep team.

Get Started – Local Environment Setup

Bicep CLI

For the local development environment, the Bicep CLI is required as a minimum requirement so that Bicep Code can be used sensibly on your own machine. In addition, it is a good idea to have the Azure CLI or the Azure modules of PowerShell installed. In the case of the Azure CLI, Bicep is even included directly. If you otherwise rely on PowerShell, you must install the engine for Bicep manually, but this is done quickly.

Visual Studio Code

Theoretically, a Bicep deployment could now be started directly, and the integrated consoles could be used to execute the commands. In practice, however, developers tend to rely on a more comfortable development environment. An excellent tool for this task is Visual Studio Code (VS Code). It is a free, resource-saving open-source solution. The environment offers useful Git integration and can be equipped with a variety of useful extensions for specific use cases. VS Code supports the developer with Bicep with features such as syntax highlighting, IntelliSense, in-code navigation and automatic formatting options. The Bicep Visualizer can clearly display the resources to be created in the development environment and with their dependencies.

When working with Bicep, the following extensions are recommended:

A good overview of the complete setup, also for the variant with the big brother Visual Studio, can be found at [6].

If you are not allowed or want to set up anything locally, you can also use DevContainer, GitHub Codespaces[7] or Azure DevBoxes[8],  for example.

This blog covered for now the basics about Bicep-Iac and how to get ready your environment to start with a first deployment. In the next posts, we will go through the general structure of the bicep templates and do a first provisioning with that approach.


[1] https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep

[2] https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-bicep

[3] https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account&ssr=false#overview

[4] https://marketplace.visualstudio.com/items?itemName=ms-vscode.azurecli

[5] https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell

[6] https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/install

[7] https://github.com/Azure/vscode-remote-try-bicep

[8] https://learn.microsoft.com/en-us/azure/dev-box/overview-what-is-microsoft-dev-box?wt.mc_id=mdbservice_acomdoc05_webpage_cnl

Leave a comment

Your email address will not be published. Required fields are marked *