Yaml Variables in Deployments

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

Intro #

Bicep deployments are typically done using one parameter file that maps directly to the Bicep file(s). 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 related 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 an environment specific variable file which is shared between multiple sequential deployments. This makes it easier to implement modular deployments for different environments. 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 Bicep resource modules. A typical landing zone scenario with virtual network provisioning is presented.

YAML based variables in bicep files #

YAML variables need to be converted to JSON format before they can be used in the deployment. Yq is a standalone program that can be used to convert variable files for the deployment. Yq is directly available in MS hosted Linux agents. There is also a inbuilt bicep YAML function available. The advantage of the standalone yq, is that script can share the same YAML variables.

Example of yq YAML to JSON conversion.

# Part of pipeline Bash task using "yq", YAML to JSON conversion
yq -P bicep-variables.json -o json > bicep-variables.json

Bicep supports loading of JSON variable files.

// 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
# file bicep-variables-dev.yml, converted to json as part of pipeline execution
#DEV
vnet:
  name: vnet-test-dev
  # only first property shown here

YAML based variables in pipeline template files #

String interpolation in a template file can also be used. The values needs to be given before pipeline execution, as in the example below. These have higher priority in deployments, see example below.

# file template-variables.yml
parameters:
  env: ''
variables:
  vnetResourceGroup: vnet-${{ parameters.env }}-rg
...


# file azure-pipelines.yml
parameters:
- name: env
  values:
  - dev
  - qa   
  - prod

variables:
- template: template-variables.yml # Simple notation in template variable file.
    env:  ${{parameters.env}} 
...
# Part of pipeline CLI task
az deployment group create \
      --resource-group ${{ variables.vnetResourceGroup }} \
      --template-file main.bicep 

Using pipeline and bicep YAML variables together #

Pipeline template files variables can be used for higher level variables such as resource names and resource groups. Lower to medium level variables may be stored in bicep YAML variable files. Having a clear separation makes it easier to achieve customer specific IaC deliveries using only variable files. This is a topic for a future article.

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. Everything is in one directory for simplicity reasons. Copy the content to the root level for pipeline execution.

Conclusions #

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 #

There is a size limitation of 4Mb for variables and bicep templates. This limit is not likely to be reached in modular or normal deployments.

References #

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