Work with environment variables in Azure Bicep

Did you know Azure Bicep can read environment variables? In this blog, we’ll explore how to use environment variables in Azure Bicep when set from an Azure Pipeline.

readEnvironmentVariable function

Alongside the release of Bicepparam is the readEnvironmentVariable function, designed to retrieve environment variables either from your deployment agent or your local computer, depending on the deployment source

Let’s take a look at the readEnvironmentVariable function. This function has two parameters:

readEnvironmentVariable(environmentVariableName: string, default: string)

The first parameter environmentVariableName is a required parameter and the default parameter is optional. The default value will be used when the environment variable cannot be found.

The function returns a string. If you expect a boolean or an integer, make sure to cast/convert it using the corresponding functions bool() or int().

It is important to know that the environment variables are loaded during compilation time and not during runtime.

Note! This function can only be used in a parameter file using Bicepparam.

readEnvironmentVariable in action

Prior to reading environment variables, it’s essential to set them. To achieve this I will leverage an Azure Pipeline, where variables configured within the pipeline automatically become environment variables.

In this example pipeline I will set a variable through a YAML parameter and the variable will be set dynamically with a randomized value:

parameters:
- name: Environment
type: string
default: dev
values:
- prod
- acc
- tst
- dev
pool:
vmImage: 'windows-latest'
variables:
- name: Environment
value: ${{ parameters.Environment }}
steps:
- powershell: |
$random = -join ((65..90) + (97..122) | Get-Random -Count 10 | ForEach-Object {[char]$_})
Write-Output "##vso[task.setvariable variable=RandomizedString]$random"
displayName: 'Set a variable from pipeline'
- task: AzureCLI@2
inputs:
azureSubscription: 'spn-readEnvironmentVariable'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment group create --template-file ./demo.bicep --parameters ./demo.bicepparam --resource-group rg-playground

In the above YAML we are setting two variables:

  • Environment – is defined through a parameter with the default value dev. Also, we define this parameter as a variable, so it’s defined as an environment variable.
  • RandomizedString – a randomly generated string created via PowerShell and is set during runtime as a variable using task.setvariable.

Now that the environment variables are in place they can now be used in the Bicepparam file.

In Bicepparam we can define parameters and variables. The variable Environment will be set as a Bicep variable for reusability purposes and the variable RandomizedString will be set as an input parameter:

using 'demo.bicep'
var varEnvironment = readEnvironmentVariable('Environment', 'dev')
param parRandomizedString = readEnvironmentVariable('RandomizedString')
param parResourceName = 'my-resource-in-env-${varEnvironment}'
view raw demo.bicepparam hosted with ❤ by GitHub

In my Bicep file (demo.bicep), we define two outputs to verify the values:

param parRandomizedString string
param parResourceName string
output outRandomizedStringEnvVariable string = parRandomizedString
output outResourceName string = parResourceName
view raw demo.bicep hosted with ❤ by GitHub

Let’s see the output of parameters parRandomizedString and parResourceName after a deployment:

Deployment output as shown in Azure

In the output from the deployment, we can see the randomized value of parRandomizedString and the value of varEnvironment in the parameter parResourceName.

Note! The approach for referencing environment variables varies between Windows and Linux platforms. In our scenario, we are utilizing the windows-latest platform, so our variable references are as follows: $env:Environment and $env:RandomizedString. However, on the Linux ubuntu-latest platform, the references should be $env:ENVIRONMENT and $env:RANDOMIZEDSTRING. Additionally, it’s important to note that the environment names in the Bicep parameter file must be in uppercase when using Linux.

What if the variable is not set?

When a parameter is defined with the readEnvironmentVariable function and the environment variable does not exist it will throw the error BCP338 during compilation time:

Error BCP338: Failed to evaluate parameter "NonExistingEnvVariable": Environment variable does not exist, and no default value set

To prevent this error, I would set a default value, which could target a development environment, for example.

Conclusion

This is how you can leverage environment variables in Azure Bicep. Using this function can make your orchestration in Azure even more flexible. Additionally, it simplifies your Azure orchestration by replacing the search and replace functionality of readEnvironmentVariable.

2 thoughts on “Work with environment variables in Azure Bicep

Leave a comment