Skip to content

Infrastructure as Code with Azure DevOps and Bicep

Bicep is a language for declaratively deploying Azure resources. You can use Bicep instead of JSON for developing your Azure Resource Manager templates (ARM templates). Bicep simplifies the developing process by providing shorter syntax and really nice intellisense support for Visual Studio Code.

Bicep is based on “.bicep” files that are written with Visual Studio Code (or any other text editor, but I recommend to use the Code). If Bicep extension is installed the Code will automatically detect the language when file is saved with .bicep file extension. After the file is written, it can be easily deployed with Az Cli tool. Az Cli tool needs to be at least version 2.2.0.0 to have the support for Bicep files.

Intellisense gives tips for different kind of resources that are available

Resources defined in Bicep files are created with az deployment command, but running commands manually is not the way we want to do it, so let’s see how we can run those Bicep files in Azure DevOps.

Create App Service with Bicep and Azure DevOps

First let’s create a new repository called IaC into Azure DevOps that holds our Bicep files.

Then open the Visual Studio Code and start writing some Bicep code (install the Bicep extension first if you don’t have it)!

param appServiceName string = 'AzureDevOpsBicepTest'
param planName string = 'AzureDevOpsBicep'
param location string = 'West Europe'

// Create Windows app service plan into west europe region. Size is F1.
resource appServicePlan 'Microsoft.Web/serverfarms@2018-02-01' = {
  name: planName
  location: location
  sku: {
    name: 'F1'
    tier: 'Free'
    size: 'F1'
    family: 'F'
    capacity: 0
  }
  kind: 'app'
  properties: {
    perSiteScaling: false
    maximumElasticWorkerCount: 1
    isSpot: false
    reserved: false
    isXenon: false
    hyperV: false
    targetWorkerCount: 0
    targetWorkerSizeId: 0
  }
}

// Create app service into our app service plan.
resource appService 'Microsoft.Web/sites@2020-06-01' = {
  name: appServiceName
  location: location
  identity: {
    type: 'SystemAssigned' // Default use system assigned ID for app service
  }
  properties: {
    serverFarmId: appServicePlan.id // Use appServicePlan variable that is defined as resource above.
    httpsOnly: true
    siteConfig: {
      minTlsVersion: '1.2' // Allow only TLS 1.2 that is good practice for security
    }
  }
}

The following code creates two new resources called “appServicePlan” and “appService“. The appServicePlan type is serverfarms, which in common language means Azure App Service Plan. For the plan we define name, that is planName variable value (AzureDevOpsBicep) and some mandatory settings like the tier and size.

One easy way to generate Bicep code is to create the resource into Azure, then export the template and use Bicep Playground to decompile the ARM template into Bicep code.

I find the Bicep code quite self-explanatory, so I’m not going to spent more time on that. Let’s see how we can run this in the Azure DevOps.

We want our Bicep code to run when the new release is created, so we should start by creating new release pipeline. In the pipeline we need to access the Bicep file from our IaC repository. The easiest way to do this is just add it as an artifact to our release pipeline.

In the agent job part we basically need two tasks. One for creating the resource group, because we are not creating one in the Bicep code, and the second task for deploying our new Bicep code. In the first task we are using PowerShell type of inline script to create the resource group called “AzureDevOpsBicepTestRg”

Create resource group with az group create
az group create --name AzureDevOpsBicepTestRg --location "West Europe"

We need to define almost same settings for Bicep task, but we also need to set the Working Directory for our inline script.

Script type is Powershell
Script location is Inline Script
Inline Script

az deployment group create --name bicepDeployment --resource-group AzureDevOpsBicepTestRg --template-file webapp.bicep

and the working directory is $(System.DefaultWorkingDirectory)/_IaC

Run Bicep file with az deployment group create command

The inline script is calling our Bicep file with deployment group create command. The resource group must match the one that we are using in the previous task (AzureDevOpsBicepTestRg).

Now when we run the deployment we can see that it is actually quite fast at deploying the App Service into Azure. If you are just testing the Bicep, remember to remove the resource group after deployment is run!

Summary

Bicep is a modern way to build infrastructure as a code solution for Azure services. It can be easily integrated into DevOps pipeline with az cli tool and it already has a quite nice development experience with Visual Studio Code. At the time of writing this post (17.3.2021) the latest Bicep version was v0.3.1, so remember to be a bit cautious when using it in the production.