Azure Bicep is a declarative language for Azure infrastructure, it is the successor of ARM (Azure Resource Manager) templates. Bicep is one of the languages through which Azure has enabled the deployment of IaC (Infrastructure as Code).
What is Infrastructure as Code
Infrastructure as Code is the declaration of compute, networking and infrastructure resources through code rather than through manual configuration and deployment. For example, the code snippet below is the declaration of a Public IP address using Bicep which is an example of IaC.
This snippet can be used to deploy the public IP rather than manually clicking through the Azure portal to achieve the same results.
Benefits of Infrastructure as Code
IaC allows for complex data platform architectures to be defined in code and so can be deployed repeatedly in different environments with very little manual effort. This can be utilised for creating identical environments in development, UAT and production environments easily. Another benefit is in a disaster recovery scenario if the platform must be built from scratch the infrastructure can be recreated by just redeploying the IaC code, rather than manually rebuilding which is timely and carries a risk of human error.
What is Bicep
Bicep is one of the Azure languages for IaC as it supports all Azure resources and API versions. Bicep was created to solve the downfalls of ARM (Azure Resource Manager) templates which previously were the only Azure native way of deploying infrastructure via IaC. ARM templates use JSON syntax, which can be long and complex to write and understand. Bicep is much more reader and writer friendly with simpler syntax. Below is a Bicep template declaring a storage account and the equivalent storage account declared using and ARM template.
Bicep doesn’t just allow for the creation of individual isolated resources, it can be used to declare and deploy entire connected data platforms. For example, see the Bicep snippet below which declares an Azure Monitor Private Linked Scope, an Application Insights, and the connection between the two resources.
Bicep also has other benefits over ARM templates too. With Bicep you don’t have to declare the order of deployment, for example with Bicep in the same template you can declare a function app, then later on declare the app service plan used to host it without explicitly having to state that the app service plan should be created first. This was not possible with ARM templates which for large deployments can result in a complex order of operations. However, ARM templates are the building blocks of Bicep and are still very widely used. When Bicep templates are compiled, they are first converted into ARM templates by the compiler then deployed.
Using Parameters with Bicep
Parameters can be used in Bicep templates so they can be reused to deploy infrastructure in different environments. Parameters can be defined in several ways, they can be declared within the Bicep file and include a default value or have their value declared at deployment. Or parameters can be included in a separate JSON file, the name of which is declared when the template is being deployed. When parameters are defined within in the Bicep file a data type must be provided and a default value can be provided but this is optional, then the parameter can be referenced using its name. For example, below the parameters ‘logsName’ and ‘retentionPolicyDays’ are declared with their data types and given default values, they are then used in the declaration of the Diagnostic Settings resource.
Secure parameters which shouldn’t be saved to the deployment history or be logged can be created using the ‘secure’ decorator, this should be used when declaring passwords as shown below.
Parameters can also be declared in a separate JSON file, this makes it easy to deploy a template to different environment as different environments can have different parameter files while the Bicep template remains the same. The parameters included in the parameter must also be declared in the Bicep file but don’t need to include a default value as the value from the parameter file will be used, if a default value for a parameter is defined in the Bicep file and a parameter file is also used the value from the parameter file will be used. An example of a parameter file is shown below which includes two parameters ‘storageAccountName’ and ‘resourceGroupName’.
Bicep in VS Code
VS Code includes an extension for Bicep, which makes developing templates easier. It can be installed through the extensions tab within VS Code. The Bicep extension includes intellisense features which shows if Bicep code is formatted incorrectly and provides information on how parameters should be filled in. It also includes a resource visualiser, which shows which resources will be deployed and how they are related, an example of the resource visualiser can be seen below showing two applications being hosted on an app service plan with an Application Insights resource.
Deploying Bicep Templates
Bicep is a declarative language so just describes what infrastructure should be deployed, not how it should be deployed, an imperative language must be used to describe how the template should be deployed. Either Azure CLI or Azure PowerShell can be used to deploy Bicep template into Azure. A PowerShell script to deploy a Bicep file is shown below, where ‘main.bicep’ is the name of the Bicep template file which declares the resources to be deployed and ‘azuredeploy.parameters.json’ is the name of the JSON file containing the parameters for the deployment.
CICD with Bicep in Azure DevOps
Bicep deployment can be done through Azure DevOps pipelines to allow for a continuous integration and continuous deployment (CICD) pipeline. This means deployments can be automatically triggered after pull requests to the Bicep repo. The code snippet below shows the YAML pipeline in Azure DevOps which can be used for CICD deployment of Bicep files.
Abigail Brown is a Data Engineer at The Oakland Group