Home Deploying Bicep Template using Azure DevOps
Post
Cancel

Deploying Bicep Template using Azure DevOps

In this short post we are going to look at automating the deployment of a Bicep template using Azure DevOps. Additionally, we are going to look at how you can convert an ARM template to Bicep.

You can find all the files used in this post on my GitHub here.

Azure Bicep is almost an abstraction of ARM (JSON) templates specifically developed for Azure and hence they are not cloud agnostic. The main difference is that Bicep is a lot more human readable and generally you need fewer lines of code to achieve the same result through the use of simple syntax.

You can read more about Bicep here

Some pre-requisites before we get started:

  • Azure CLI - Download here https://learn.microsoft.com/en-us/cli/azure/install-azure-cli
  • Azure DevOps Access
  • Azure Subscription

Converting an ARM Template to Bicep

With the Azure CLI Microsoft provides functionality for you to decompile an ARM/JSON template to Bicep. This is extremely useful if you have existing deployments, and you want to start managing them with Bicep.

For this tutorial we are going to perform a simple resource group deployment. Let’s look at our ARM template. It’s split into a template.json file which has the definition of what we want to deploy and a parameters.json where we provide specific named variables required by the template.json.

It’s worth noting that the parameters file does not need to be converted. This remains in a JSON format.

Template File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.1",
  "parameters": {
      "rgName": {
          "type": "string"
      },
      "rgLocation": {
          "type": "string"
      },
      "tags": {
          "type": "object",
          "defaultValue": {}
      }
  },
  "variables": {},
  "resources": [
      {
          "type": "Microsoft.Resources/resourceGroups",
          "apiVersion": "2018-05-01",
          "location": "[parameters('rgLocation')]",
          "name": "[parameters('rgName')]",
          "properties": {},
          "tags": "[parameters('tags')]"
      }
  ],
  "outputs": {}
}

Parameter File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "rgName": {
            "value": "arm-template-test-rg"
        },
        "rgLocation": {
            "value": "australiaeast"
        },
        "tags": {
            "value": {}
        }
    }
}

Let’s convert our template to Bicep

1: Make sure you have the Azure CLI installed on your local machine. Navigate to the folder containing your ARM template and run the following command:

1
az bicep decompile --file template.json

Image description

Once the process completes, you will notice another file has been added to the directory called template.bicep. This is our converted template.

2: Let’s review the code for our new bicep file:

1
2
3
4
5
6
7
8
9
10
11
12
13
targetScope = 'subscription'
param rgName string
param rgLocation string
param tags object = {
}

resource rg 'Microsoft.Resources/resourceGroups@2018-05-01' = {
  location: rgLocation
  name: rgName
  properties: {
  }
  tags: tags
}

Here you can notice straight away how the template is much shorter and more concise. We went from 28 lines of code to 13. It’s worth noting that the conversion for bigger files can have some issue with naming formats so you may need to do some polishing before it’s done. We can use our existing JSON parameter file to supply the values required.

Deploy the template manually

Let’s deploy the template manually to make sure it works using the Azure CLI.

1: Run the following Azure CLI command. Make sure to replace the template and parameter file name if you used something different in the previous step.

1
2
3
4
5
az deployment sub create `
  --name TestDeployment `
  --location australiaeast `
  --template-file template.bicep `
  --parameters parameters.json

Image description

We can now see the RG is ready in the Azure portal.

Image description

Let’s delete the RG and deploy the same templates using Azure DevOps for full automation.

Deploy the template using Azure DevOps

1: Create a new pipeline from Azure DevOps by navigating to Pipelines and then New pipelines

Image description

2: Select Azure Repos Git for your code repository

Image description

3: Select Starter pipeline

Image description

4: Paste the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
trigger:
- master

name: Deploy Bicep files


variables:
  vmImageName: 'ubuntu-latest'

  azureServiceConnection: 'devops-poc3-deploy-spi'
  location: 'australiaeast'
  templateFile: 'bicep/azure_resource_group/template.bicep'
  templateParameterFile: 'bicep/azure_resource_group/parameters.json'
pool:
  vmImage: $(vmImageName)

steps:
- task: AzureResourceManagerTemplateDeployment@3
  inputs:
    deploymentScope: 'Subscription'
    azureResourceManagerConnection: '$(azureServiceConnection)'
    action: 'Create Or Update Resource Group'
    location: '$(location)'
    templateLocation: 'Linked artifact'
    csmFile: '$(Build.SourcesDirectory)/$(templateFile)'
    csmParametersFile: '$(Build.SourcesDirectory)/$(templateParameterFile)'
    deploymentMode: 'Incremental'
    deploymentName: 'DeployPipelineTemplate'

In this scenario I am providing the template and parameter file as a linked artifact in Azure DevOps by specifying the location in the following parameters csmFile & csmParametersFile. The pipeline also has a trigger for CD so every merge to the main/master branch will re-run it. Since we are using incremental deployments this is pretty safe to do.

5: Save the pipeline and run it.

Image description

We have now deployed the resource group through Azure DevOps using Bicep.

Image description

In the next post we are going to look at how to perform some automated tests on our Bicep deployment using the same pipelines including code linting, deployment validation, what-if checks and approval gates.

This post is licensed under CC BY 4.0 by the author.