How to Use JSON Parameters in Bicep Template

Written by pa1 | Published 2022/09/05
Tech Story Tags: azure-devops | iac | azure-bicep

TLDRBicep is an Azure Native Infrastructure As Code tool to manage Azure Cloud Resources. The tool uses a declarative style on top of the ARM Templates. It is very concise and doesn’t need knowledge of Programming languages. The parameters can be passed as Parameter. files following Arm Template Schema or they can be. passed inline through. az deployment group command or it can be a combination of files and. inline. parameters. You can manage parameters as normal. JSON string instead of files. This can be minified and managed through Azure Devops Variables.via the TL;DR App

Hello Techies,

I am sure you all must have heard Bicep new kid around the Microsoft Block to do Infrastructure As Code (IAC) (Domain Specific Language) to manage the deployments of Azure Resources. This is a great learning module from Microsoft which covers basics to advanced.

Introduction to Bicep Templates

BICEP is an Azure Native Infrastructure As Code tool to manage Azure Cloud Resources. This uses a declarative style. This is an abstraction on top of the ARM Templates. If you have worked with ARM Templates, you know how difficult is to create one from the scratch and also very verbose. Bicep templates are very concise. Under the hood, they get compiled into Arm Templates by the az deployment group command before it is sent to Azure for Deployment

Few Advantages of Bicep over ARM templates or Terraform

  • As Bicep is native to Azure, it supports all the preview and GA versions right from the day Microsoft Releases. On Terraform you need to wait for the providers to get updates.

  • Very concise and doesn’t need knowledge of Programming languages, married with VS Code Extension, save the file with .bicep extension, and intelli-sense kicks in to help you write the template.

  • Bicep Template deployments are idempotent, they can be split into modules for re-usability and optionally those modules can be published to ACR to achieve standardization across the enterprise. No state is managed like Terraform and it is Free.

Let’s if you already have ARM Templates, you can convert them to Bicep Templates by using decompile command.

az bicep decompile --file main_armteplate.json

Also, there is a build command if you wish to see how the generated Arm Template looks. You don’t need to use this command to deploy. More commands can be found here.

Passing Parameters

Similar to ARM Templates, you can parametrize your Bicep templates. These parameters can be passed as Parameter JSON files following Arm Template Schema or they can be passed inline or they can be passed inline through az deployment group command or it can be a combination of files and inline params (In this scenario inline params will override params defined in the file)

More on Different ways to pass the parameters to the Bicep Template can be found here.

Problem Context

Few problems that I face when managing Bicep Params as files are

  1. They don’t support dynamic values, for example if want to pass different skus for different environments only way is to create different param files (like Standard LRS for DEV and Standard RAGZRS for Production).
  2. Passing Bicep Object Param through inline is not possible (At least I didn’t find a way).

My Solution

These problems can be solved by managing params as normal JSON string instead of files. This JSON string can be minified and managed through Azure Devops Variables and pass as Inline param. Now that is just a Json string, you can use other devops managed variables inside this string, which can make it more dynamic.

We can achieve this by using JSON Bicep Functions.

The below example is to pass a normal JSON Object(Not Arm Schema based) to the Bicep Template as an inline Parameter.

param storageJsonString string
param location string = resourceGroup().location

#Using Json Function to parse the Json string to json object
var storageConfig = json(storageJsonString)

resource storage_account 'Microsoft.Storage/storageAccounts@2021-09-01'= {
  kind: storageConfig.kind
  name: storageConfig.name
  location: location
  sku: {
    name: storageConfig.sku
  }
  properties: {
    allowBlobPublicAccess: true
    accessTier: 'Hot'
  }
}

Call this from PowerShell by passing an inline JSON string parameter to this template.

$stg = '{\"name\":\"pa1pocstg\",\"sku\":\"Standard_LRS\",\"kind\":\"StorageV2\"}'
az deployment group create --resource-group $rg `
--template-file .\Bicep101\bicep-json.bicep `
--parameters storageJsonString=$stg

How to refer to other Azure DevOps Variables

Let’s say you have Azure DevOps Variable called env. The value for this variable is different for every stage. Example env is set to “dev” in Dev Stage of the Pipeline and “QA” for QA Stage of Pipeline”.

You can simply refer to them with $(env) syntax or if they are used in variables template,

${{ variables.env }}. More about Azure DevOps Variables.

'{\"name\":\"pa1poc$(env)\",\"sku\":\"Standard_LRS\",\"kind\":\"StorageV2\"}'
#Pay Attention to $(env) in the name

Conclusion

Here I have given the background of Bicep Templates and provided a solution for the problems of managing Parameters through JSON files. Please, let me know what you think of it.


Also published here.


Published by HackerNoon on 2022/09/05