top of page

Use Bicep to create ARM template

This page will explain how to create a template using Bicep. 

Full Bicep code in the bottom creating a storage account with all bells and whistles 

Bicep is a way to simplify creation of ARM temples.

To shorten the production of ARMs you can use Bicep. In Visual Studio Code download the extension Bicep.

If you have read my ARM template blog, you already have the ARM extension installed as well as the Azure Cli tool. 

To simplify this even more there is some sites you should visit. First, more and more artifacts shown on sites explaining artifact functions have Bicep examples that could be good as a startup. As well as GitHub quick start and my favorite Bicep Playground. here you can see the ARM at the same time as you write your Bicep code.

A nice command I used a lot to understand Bicep is decompile that could take a working ARM into Bicep code. Looks like this running azcli:

az bicep decompile --file XXX.json

Bicep is designed in a similar way as ARMs designing a parameter looks like this.

param storageAccountName string

To this parameter you can add metadata like adding descriptions, datatype, defaults, and inherit values from Azure.

  • Add description

@description('Specifies the name of the Azure Storage account.'). 

In the ARM it's going to be:    

 "metadata": {

        "description": "Specifies the name of the Azure Storage account."

      }

  • Data Type is selected after the param name and can be string, int, bool, object and array. An array uses square brackets to define its elements.

  param location string = resourceGroup().location 

In ARM:

"type": "string",

You probably grasp the idee how meta data in params work now. All of the variants shows via intellisense.

A bit further down in the code you get the Azure resources them self and version as well.

resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2019-06-01'

By using the parameters as well as using values you get from known object like the Resource Group, it very easy to build release pipelines in DevOps etc.  

Creating an ARM template from Bicep use the AZCLI command in the terminal window :

az bicep build --file BicepFileName.bicep --outfile ArmFileName.json

Show result 

The code below shows a code including almost all parameters creating a storage account and is a nice example for most of the complexity you run into. 

Full Code:

@description('Specifies the name of the Azure Storage account.')

param storageAccountName string

 

@description('Specifies the location in which the Azure Storage resources should be deployed.')

param location string = resourceGroup().location

 

@description('Specifies array of Container params')

param containerName array = [

  'cont-1'

  'cont-2'

  'cont-3'

]

 

@description('Secifies SKU(Stock Keeping Unit) for StorageAccount')

@allowed([

  'Standard_LRS'

  'Standard_GRS'

  'Standard_ZRS'

  'Premium_LRS'

])

param storageSKU string = 'Standard_LRS'

 

@description('Specifies accessTier')

@allowed([

  'Hot'

  'Cool'

])

param accessTier string = 'Hot'

 

@description('Specifies Hierarchical namespace true or false Bool')

param isHnsEnabled bool = false

 

@description('specifie allowBlobPublicAccess true or fale bool')

param allowBlobPublicAccess bool = true

 

@description('Specifies Soft delete true or false bool')

param softDeleteOn bool = false

 

@description('Specifies retention policy on soft delete in days')

param retentionDays int = 7

 

@description('Specifies Soft delete true or false bool')

param containerDeleteRetentionPolicy bool = false

 

@description('Specifies retention policy on soft delete in days')

param containerRetentionDays int = 7

 

@description('Specifies If versioning is enabled true or false bool')

param IsVersioningEnabled bool = true

 

@description('Specifies minimumTlsVersion (Transport Layer Security)')

param minimumTlsVersion string = 'TLS1_2'

 

resource storageAccountName_resource 'Microsoft.Storage/storageAccounts@2021-04-01' = {

  name: storageAccountName

  location: location

  kind: 'StorageV2'

  sku: {

    name: storageSKU

  }

  properties: {

    accessTier: accessTier

    isHnsEnabled: isHnsEnabled

    allowBlobPublicAccess: allowBlobPublicAccess

    minimumTlsVersion: minimumTlsVersion

  }

}

 

resource blobServices 'Microsoft.Storage/storageAccounts/blobServices@2019-06-01' = {

  parent: storageAccountName_resource

 

  name: 'default'

  properties: {

    cors: {

      corsRules: []

    }

    deleteRetentionPolicy: {

      enabled: softDeleteOn

      days: retentionDays

    }

    containerDeleteRetentionPolicy: {

      enabled: containerDeleteRetentionPolicy

      days: containerRetentionDays

    }

    isVersioningEnabled: IsVersioningEnabled

   

  }

}

 

resource storageAccountName_default_containerName 'Microsoft.Storage/storageAccounts/blobServices/containers@2021-04-01' = [for i in range(0, length(range(0, (length(containerName))))): {

  name: '${storageAccountName}/default/${containerName[i]}'

  dependsOn: [

    storageAccountName_resource

  ]

}]

FullCode
bottom of page