How to access pipeline variables in conditions - azure

I have pipeline where running template as one of steps.
I need execute template with two different scopes of parameters depends on value of one of pipeline variable.
For example, if pipeline variable 'mode' has value 'dev', I need run template with one scope, if value is 'stage', another scope.
- ${{ if eq(parameters.mode, 'dev') }}:
- template: ../template.yaml
parameters:
mode: dev
namespace: dev-namespace
fqdn: dev-fqdn
- ${{ if eq(variables.mode, 'staging') }}:
- template: ../template.yaml
parameters:
mode: staging
namespace: staging-namespace
fqdn: staging-fqdn

You should use this syntax ${{ if eq(variables['mode'], 'staging') }}:

It depends at what time the variables will be read in at and used. There are more then possible answer.
If using these for the future execution of a template I'd recommend using condition and defining the parameters you have in separate yml variable files.
condition: eq('${{ variables.mode}}', 'staging)
That way the call would be just
job:
condition: eq('${{ variables.mode}}', 'staging')
variables: staging.yml
- template: ../template.yaml
parameters:
mode: ${{ variables.mode }}
namespace: ${{ variables.namepsace }}
fqdn: ${{ variables.fqdn }}
And staging.yml would look like:
variables:
mode: staging
namespace: staging-namespace
fqdn: staging-fqdn
This way it is a little less decoupled and scalable not having to hard code it every time.

1.If you're using runtime parameters, you can use this format:
trigger:
- master
parameters:
- name: mode
displayName: Choose mode
type: string
default: dev
values:
- dev
- staging
pool:
vmImage: 'windows-latest'
steps:
- ${{ if eq(parameters.mode, 'dev') }}:
- template: template.yml
parameters:
mode: dev
- ${{ if eq(parameters.mode, 'staging') }}:
- template: template.yml
parameters:
mode: staging
For more details you can check Parameters to select a template at runtime.
2.If you're using variables defined in yaml directly, check my another sample:
trigger:
- master
variables:
mode: staging
pool:
vmImage: 'windows-latest'
stages:
- stage: Dev
condition: eq(variables.mode, 'dev')
jobs:
- job:
steps:
- template: template.yml
parameters:
mode: dev
- stage: Staging
condition: eq(variables.mode, 'staging')
jobs:
- job:
steps:
- template: template.yml
parameters:
mode: staging
I would recommend runtime parameters way cause it's more convenient and much more flexible.
Update1:
Here's my simple template.yml file which is just for test:
parameters:
- name: mode
type: string
default: default
steps:
- script: echo ${{ parameters.mode }}

Related

Variables not getting referenced while calling the shell script in the azure pipelines

This is my first time working with azure pipelines, I started creating my azure-pipeline.yml. I am trying to execute the azure DevOps pipeline. However I am getting to errors where the variable are not referenced as declared.
deploy.sh deploy_azr ${{ variables.subPref }} ${{ variables.rgType }} ${{ variables.location }} ${{ variables.config }}
Here is the start of my template
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
branches:
include:
- main
paths:
include:
- 'bicep/*'
- 'azure-pipelines.yml'
exclude:
- '*'
pool:
vmImage: ubuntu-latest
variables:
${{ if eq(variables['Build.SourceBranchName'], 'test_branch') }}:
deployTarget: tst
subscription: testsubscription
subscriptionId: 26455-trt31-******
rgType: tstrg
subPref: *****
config: tstjson
location: eastus2
${{ if eq(variables['Build.SourceBranchName'], 'main') }}:
deployTarget: prd
subscription: prdsub
subscriptionId: ***********************
rgType: prdrg
subPref: ******
config: prd.json
location: eastus2
stages:
- stage: Deploylib
jobs:
- deployment: lib
environment: ${{ variables.subscription }}
strategy:
runOnce:
deploy:
steps:
- checkout: self
- task: AzureCLI#2
inputs:
azureSubscription: ${{ variables.subscription }}
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
set -e
set -x
sudo apt install -y gridsite-clients
cd 'bicep'
echo "starting the lib deployment"
deploy.sh deploy_azr ${{ variables.subPref }} ${{ variables.rgType }} ${{ variables.location }} ${{ variables.config }}
any help would be appreciated.
I think the problem is that you need to specify the correct environment name on this line,
jobs:
- deployment: lib
environment: <environment name>
You can create an environment on the DevOps page, see the reference here, then copy the name to the YAML above.
The concept of environment here represents a collection of resources you will deploy your code. Once you have run a deployment, you should be able to see the history of deployment in the target environment.
/azure-pipelines.yml (Line: 42, Col: 22): Unexpected value ''
Test the same YAML sample and reproduce the same issue.
The cause of the issue is that you are using the format: ${{ variables.subscription }} in YAML sample.
The variable will be processed at compile time.
To solve this issue, you can change to use the format: $(subscription)
For example:
jobs:
- deployment: lib
environment: $(subscription)
Result:
For more detailed info, you can refer to this doc: Runtime expression syntax

Conditional Approval in pipeline jobs in azure pipelines

I want to customize environment attribute to choose programmatically environment for approval (dev, preprod, prod). When I try to launch pipeline, I see this error. Is there an alternative?
Job : Environment $(environment) could not be found. The environment does not exist or has not been authorized for use.
variables:
environment: dev
jobs:
- deployment: test
displayName: test
timeoutInMinutes: 0
# creates an environment if it doesn't exist
environment: $(environment)
strategy:
runOnce:
deploy:
steps:
- checkout: self
clean: true
displayName : Checkout repository
- task: NodeTool#0
inputs:
versionSpec: '16.x'
checkLatest: true
For this use case you should use parameters. This is because variables are not available during the initial parsing stage of the pipeline.
parameters:
- name: "environment"
type: string
default: "development"
And then environment: ${{ parameters.environment }}
Or if you want to get fancy, you could do something like this:
parameters:
- name: "environments"
type: object
default:
- name: development
param1: value
param2: value
- name: test
param1: value
param2: value
# This will look through the environment parameter and create a job for each environment.
- ${{ each environment in parameters.environments }} :
jobs:
- deployment: test
#read in vars from a file in variables/development.yml
variables: variables/${{ environment.name }}.yml
displayName: test
timeoutInMinutes: 0
# creates an environment if it doesn't exist
environment: ${{ environment.name }}
strategy:
runOnce:
deploy:
steps:
- checkout: self
clean: true
displayName : Checkout repository
- task: NodeTool#0
inputs:
versionSpec: '16.x'
checkLatest: true

Azure pipeline - Stage condition dependson

I have three environments: dev, hml and qa.
In my pipeline depending on the branch the stage has a condition to check whether it will run or not:
- stage: Project_Deploy_DEV
condition: eq(variables['Build.SourceBranch'], 'refs/heads/dev')
dependsOn: Project_Build
- stage: Project_Deploy_HML
condition: eq(variables['Build.SourceBranch'], 'refs/heads/hml')
dependsOn: Project_Build
I'm doing the qa stage, and I'd like to put a condition, depending on the branch, the dependson parameter will change:
- stage: Project_QA
condition:
${{ if eq(variables['Build.SourceBranchName'], 'dev') }}:
dependsOn: 'Project_Deploy_DEV'
${{ if eq(variables['Build.SourceBranchName'], 'hml') }}:
dependsOn: 'Project_Deploy_HML'
However, the condition above is not working, would anyone know the best way to perform this condition?
Thanks
From your YAML sample, it seems that there is a format issue. When you use if expression, there is no need to add condition field in YAML.
You can try the following sample and check if it can work.
stages:
- stage: A
jobs:
- job: test
steps:
- xxx
- stage: B
jobs:
- job: test
steps:
- xxx
- stage: C
${{ if eq(variables['Build.SourceBranchName'], 'main') }}:
dependsOn: A
${{ if eq(variables['Build.SourceBranchName'], 'dev') }}:
dependsOn: B
jobs:
- job: test
steps:
- xxx

Azure ARM template : Setting parameter value using a variable

I'm trying to pass the environment parameter to a template and then to another template (line webAppName: 'my-webapp-${{parameters.environment}}')
I get the error : A template expression is not allowed in this context. Is it not possible to do that ?
main pipeline (just the necessary code for clarity)
- stage: deploy
displayName: 'Deploy Dev Stage'
dependsOn: build
condition: succeeded()
jobs:
- deployment: deploymentjob
displayName: deployment job
environment: dev
variables:
- template: variables/dev.yml
strategy:
runOnce:
deploy:
steps:
- template: templates/pipeline-deploy/master.yml
parameters:
environment: 'dev'
master.yml
parameters:
environment: ''
steps:
- template: webapp.yml
parameters:
webAppName: 'my-webapp-${{parameters.environment}}'
then webapp.yml
parameters:
webAppName: ''
steps:
- task: AzureRmWebAppDeployment#4
displayName: 'Deploy my app'
inputs:
azureSubscription: '(#some id)'
WebAppName: ${{parameters.webAppName}}
packageForLinux: '$(workFolder)/my-package.zip'
I don't believe you're allowed to use variable substitution in ARM template parameters. But you ARE allowed to do so in variables.
So in master.yml, define a variables section, and compose your webAppName as a variable. Then pass that variable into webapp.yml instead of using a parameter.
The problem was the indentation in one of my YAML files, which was not correct. Adding an extra tab solved it.

Azure Devops: How to set group variable with if statement

I'm trying to set the variable group according to one varible that exists in the pipeline. The yaml looks like this:
But i'm getting the following error when i'm running the pipeline:
If i remove the "- group : QA" or "- group : PROD" the pipeline runs without any problem. What am I doing wrong?
This is slightly different solution but you may achieve your goal - which is if I understood conditional selection of variable group.
You can use runtime parameters:
parameters:
- name: environment
displayName: Environment
type: string
default: QA
values:
- QA
- PROD
stages:
- stage:
displayName: 'Build and Restore'
variables:
- group: ${{ parameters.environment }}
jobs:
- job:
steps:
- script: echo $(name)
than running a build you can select your envrionment:
Note: I have defined two variable groups QA and PROD with variable name in both groups.
Try with below schema:
variables:
isProd: true
stages:
- stage: Test
displayName: Build and restore
variables:
- ${{ if eq(variables['isProd'], 'false') }}:
- group: QA
- ${{ if eq(variables['isProd'], 'true') }}:
- group: PROD
jobs:
- job: A
steps:
- bash: echo $(groupname)
Note: You may receive some red warning when you defining above YAML scipt. Ignore that confused warning and continue to run it.

Resources