Skip to content
Niklas Forsbäck edited this page Jan 6, 2023 · 28 revisions

Bicep deployments using YAML based variables (Azure, DevOps, Bicep)

Intro

Bicep deployments are typically done using one parameter file that maps directly to the Bicep file. Each parameter file needs to have exact parameter match for the deployment to succeed. This leads to a situation where parameter files are hard to share for other deployments. Variables can be used instead of parameters. It has both advantages and some drawbacks such as secure parameters. The advantage is that you can create a variable file which is shared between multiple related deployments. This makes it easier to implement modular deployments. Using a YAML based variable definition makes the variable file easier to maintain, as it is more human readable than the JSON format. We will be using MS provided Bicep resource modules in the example (https://github.com/Azure/ResourceModules). These contains extensive and well defined Bicep templates with related documenation. A typical landing zone scenario with virtual network provisioning is presented.

YAML based variables

YAML variables need to be converted to JSON notation before they can be used in the deployment. Yq is a standalone program that can be used to convert variable files for the deployment.

# Part of pipeline Bash task
yq -P variables-dev.yml -o json > bicep-variables.json

Bicep supports loading of JSON variable files. It is possible to further point deeper into the JSON properties, but this is omitted here for simplicity.

// main.bicep
param landingZone object = loadJsonContent('bicep-variables.json') // Generated by yq converter (YAML-> JSON)loadJsonContent('bicep-variables.json')
param vnetName string = landingZone.vnet.name  // Reads from bicep-variables.json properties

YAML variables with more complex data structures cannot be used as template variables for the pipeline or scripts. Only string, boolean and numbers are supported for template file variable templates. A separate YAML template file can be used for shared variables between pipeline scripts and bicep deployments. One other alternative is to have a special section in the YAML file and extract those variables with simple YAML notation using "yq".

// main.bicep
loadJsonContent('template-variables.json')   // Shared YAML variables for scripts and bicep deployments converted to JSON
loadJsonContent('bicep-variables.json')  // Only for bicep deployments

param vnetName string = landingZone.vnet.name  // Reads from bicep-variables.json properties
param vnetResourceGroup string = variables.vnetResourceGroup // Reads from template-variables.json file. 
                                                             // Note that variables is the root property in this case. 
                                                             // Otherwise it cannot be used as template variable for scripts at pipeline level. 

YAML template file string interpolation in bicep deployments

String interpolation in a template file can also be used. The values needs to be give at deployment time, as in the example below. These have higher priority. YAML variables containing string interpolation are not usable as such and can be filtered out with yq during conversion to JSON.

# Part of pipeline CLI task
az deployment group create \
      --resource-group ${{ variables.vnetResourceGroup }} \
      --template-file main.bicep \
      --parameters vnetName=${{ variables.vnetName }}   // This will override previous vnetName if given.

Example

The DevOps repository contains an example of vnet provisioning using MS provided bicep resource modules. YAML based variables are converted to JSON and loaded into the bicep main file.

Advantages

Modular and sharable variable files are easier to maintain across different deployments. Readability is improved when using YAML format as a source for the variable definitions.

Drawbacks

In some cases a separate parameter file might be needed. It would only contain a few parameters.

References

  1. Bicep resource modules, https://github.com/Azure/ResourceModules
  2. yq, yaml <-> json converter, https://github.com/mikefarah/yq

Clone this wiki locally