I’m trying to use Azure devops pipelines to deploy azure resources using a bicep file.
This process works if I use powershell to deploy but I’m hitting a problem with devops.
In the bicep file I have the following
param environmentType string
var stgSubID = 'xxxx'
var prodSubID = 'xxxx'
var subscriptionID = (environmentType == 'prod') ? prodSubID : stgSubID
By entering prod or stg at deployment time I can set certain other values further down the file.
In devops I created the following pipeline but it failed because the subscriptionID
wasn’t present. I’d like to keep the conditional variable rather than creating duplicate pipelines as this will only complicate pipelines that run after this..
After some searching I came across this approach but it also fails.
trigger: none
pool:
vmImage: ubuntu-latest
variables:
- name: environment
value: $(environment)
- name: environmentType
${{ if eq( variables['environment'], 'stg') }}:
value: $(stgSubID)
${{ if eq( variables['environment'], 'prod' ) }}:
value: $(prodSubID)
jobs:
- job:
steps:
- task: AzureResourceManagerTemplateDeployment@3
inputs:
connectedServiceName: $(ServiceConnectionName)
location: $(location)
deploymentName: $(deploymentName)
resourceGroupName: $(ResourceGroupName)
csmFile: templates/newRegion.bicep
csmParametersFile: deployments/newRegion/$(shortlocation)-$(environmentType).parameters.json
overrideParameters: >
-connectivitySubID $(connectivitySubID)
-stgSubID $(stgSubID)
-prodSubID $(prodSubID)
-managementSubID $(managementSubID)
-subscriptionID ${{variables.environmentType}}
TL:DR How do a set variable X to the value of another variable in Azure devops based on the input provided at run time and pass that to a bicep file for deployment.
2
Answers
You have what appears to be a typo in your YAML. You set
environment
to be equal to the value ofenvironment
, which is going to resolve to empty. If it’s a variable that’s being entered at deployment time, please refer to the documentation on variables and compilation-time expressions (${{}}
). Runtime variables exist after compilation time, so your variable cannot resolve; you cannot use runtime variable values in compilation-time expressions.The correct way to address this is to use multiple stages. Have a stage for STG and a stage for PROD. Then you can choose the stage to deploy at deployment time via the built-in stage selection UI. You can extract the job to a template and expose parameters where appropriate.
Although I think you need to refactor your approach as other guys stated I will answer your question: TL:DR How do a set variable X to the value of another variable in Azure DevOps based on the input provided at run time and pass that to a bicep file for deployment.
According to your example, you have 3 pipeline variables:
When you set environment = stg during pipeline execution then environmentType variable which you will be passing to deployTask should be set to $(stgSubID) else $(prodSubID).
You can resolve this problem by introducing an additional job that will determine the variable and output it to another job using the output variables
Verification:
Pipeline variables value:
$(stgSubID) = 1
$(stgProdID) = 2
Test 1:
Execute pipeline with environment set to ‘stg’.
Result: environmentType = 1
Test 2
Execute pipeline with environment set to ‘prod’.
Result: environmentType = 2
If you need to use this approach I should at least recommend using the parameter with a restricted list of values stg, prod instead of environment variable.