I have the following YAML pipeline that I cannot seem to get working based on the conditional values.
parameters:
- name: "workloads"
type: object
default:
wkld001: update
wkld002: "delete"
wkld003: "update"
wkld004: "update"
wkld005: "update"
wkld006: "update"
- name: "environment"
type: string
values:
- prd
- dev
- name: "landing_zone"
type: string
values:
- private
- integration
stages:
- stage:
jobs:
- job: create_params
steps:
- powershell: |
write-host "test"
- ${{each item in parameters.workloads}}:
- ${{ if eq(parameters.workloads[item.key].value, 'update') }}:
- job: "${{item.key}}"
dependsOn: create_params
steps:
- powershell: |
write-host "testing loop - ${{item.value}}"
What i want to do is have a specific command run based on the value set for the workload map.
When I run the above no conditions are met so only the pre-job runs.
The expected behaviour is the loop runs, and the right job is spawned based on the map conditions.
The example only shows the "update" condition only; I plan to have a few more.
I got there in the end with this.
pool:
name: "UOLUKSSHPOOL01"
parameters:
- name: "workloads"
type: object
default:
wkld001: update
wkld002: "delete"
wkld003: "update"
wkld004: "update"
wkld005: "update"
wkld006: "update"
- name: "environment"
type: string
values:
- prd
- dev
- name: "landing_zone"
type: string
values:
- private
- integration
stages:
- stage:
jobs:
- job: create_params
steps:
- powershell: |
write-host "test"
- ${{each item in parameters.workloads}}:
- ${{ if eq(item.value, 'update') }}:
- job: "${{item.key}}"
condition:
dependsOn: create_params
steps:
- powershell: |
write-host "testing loop - ${{item.value}}"
Related
I have two yaml files. One is azure-pipeline.yml
name: test-resources
trigger: none
resources:
repositories:
- repository: pipeline
type: git
name: test-templates
parameters:
- name: whetherYesOrNo
type: string
default: Yes
values:
- Yes
- No
extends:
template: pipelines/ansible-playbook-deploy.yml#pipeline
parameters:
folderName: test-3scale
As for this file, when I run the pipeline, I could choose Yes or No as options before running it.
The other one is the playbook.yml for Ansible
- hosts: localhost
connection: local
become: true
vars_files:
- test_service.yml
- "vars/test.yml"
collections:
- test_collection
tasks:
- name: Find out playbooks pwd
shell: pwd
register: playbook_path_output
no_log: false
- debug: var=playbook_path_output.stdout
- name: echo something
shell: echo 'test this out'
register: playbook_ls_content_output
no_log: false
- debug: var=playbook_ls_content_output.stdout
I wish to add a condition in the playbook.yml task, so that
When I choose "Yes" when running the pipeline, task named "echo something" will run, but if I choose "No", this task will be skipped. I am really new in yaml syntax and logic. Could someone help? Many thanks!
These runs successfully on my side(I can judge the condition with no problem, at compile time it will be expanded.):
azure-pipeline.yml
trigger: none
parameters:
- name: whetherYesOrNo
type: string
default: Yes
values:
- Yes
- No
extends:
template: pipelines/ansible-playbook-deploy.yml
parameters:
whetherYesOrNo: ${{parameters.whetherYesOrNo}}
ansible-playbook-deploy.yml
parameters:
- name: whetherYesOrNo
type: string
default: No
steps:
- ${{ if eq(parameters.whetherYesOrNo, 'Yes') }}:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host "Hello World"
Repository structure on my side:
If Yes:
If No:
HI Azure pipeline i am getting struck and having error while doing this
parameters:
- name: applications_module
displayName: Applications
type: boolean
default: 'false'
values: []
- name: management_module
displayName: Management
type: boolean
default: 'false'
values: []
- name: Creation
displayName: Creation
type: boolean
default: 'false'
values: []
variables:
- name: FilterValue
${{each item in parameters}}:
${{if contains(item.name, '_module')}}:
value: item.name # here I want to concatenate all the parameters names that have name _module but this statement is throwing an error
I am not able to its saying "'value' is already defined" so can anyone help me regarding this
using ##VSO we can do that
steps:
- ${{ each parameter in parameters }}:
- bash: echo '##vso[task.setvariable variable=allParametersString]$(allParametersString)${{ parameter.Key }}'
- script:
echo 'concatenated strings by comma .->$(allParametersString)'
My ci_pipeline.yml contains the following:
- stage: DeployDEV
pool:
vmImage: 'windows-latest'
variables:
- group: [REDACTED]
- name: test_var
value: firstval
jobs:
- job: BuildDeploy
displayName: "REDACTED"
steps:
- script: echo "test_var = $(test_var)"
displayName: first variable pass
- bash: echo "##vso[task.setvariable variable=test_var]secondValue"
displayName: set new variable value
- script: echo "test_var = $(test_var)"
displayName: second variable pass
name: Env
displayName: "Extract Source Branch Name"
- template: pipeline_templates/ci_pipeline_templates/build_deploy_dev.yml
parameters:
testvar: $(test_var)
and in the build_deploy_dev.yml template:
parameters:
- name: testvar
jobs:
- job: Test
displayName: "Testjob"
steps:
- script: echo "test_var=${{ parameters.testvar }}"
name: TestVar
displayName: 'test'
I need to be able to modify the variable in the main yml file BEFORE passing it into the template. However, test_var still remains as firstval. What am I doing wrong? It seems like the change is successful in the main yml file. The second variable pass script displays test_var=secondValue. How to make the change be permanent so the template can have it ?
As stated above: Parameters are evaluated in compile time. So, using parameters won't solve your problem, however you can create a new variable as an output and make your template job dependent from the job which generates a new variable afterwards you can use it in your template as follows:
ci_pipeline.yml
- stage: DeployDEV
pool:
vmImage: 'windows-latest'
variables:
- group: [REDACTED]
- name: test_var
value: firstval
jobs:
- job: BuildDeploy
displayName: "REDACTED"
steps:
- script: echo "test_var = $(test_var)"
displayName: first variable pass
- bash: echo "##vso[task.setvariable variable=new_var;isOutput=true]SomeValue"
displayName: set new variable value
name: SetMyVariable
name: Env
displayName: "Extract Source Branch Name"
- template: pipeline_templates/ci_pipeline_templates/build_deploy_dev.yml
Then in your build_deploy_dev.yml you can use the variable you've created previously:
jobs:
- job: Test
variables:
test_var: $[ dependencies.BuildDeploy.outputs['SetMyVariable.new_var'] ]
displayName: "Testjob"
dependsOn: BuildDeploy
steps:
- script: echo "test_var=$(test_var)"
name: TestVar
displayName: 'test'
Note that you can still leverage your $(test_var) for instance to check whether it has the value 'firstValue' and then in case positive you create the 'newVar' and use it on the other job, you could even use the value of $(test_var) in your 'newVar' and use the value which you previously set:
- bash: echo "##vso[task.setvariable variable=new_var]$(test_var)"
displayName: set new variable value
In this way you can dynamically 'change' the behavior of your pipeline and keep your template file.
Unfortunately you cannot use variables set during runtime, ie. $test_var, as parameters for templates. Think of templates less like functions and more like snippets. The pipeline essentially swaps the guts of the template for the reference to the template and all parameters are evaluated at that time and swapped.
So when you set $test_var to 'firstval', the template is evaluated at that time and the parameter is set to 'firstval' as well. Then when you set $test_var later in the yaml, it is too late. See the documentation below:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops#context
It may feel dirty to reuse code but unfortunately this would be the recommended solution.
- stage: DeployDEV
pool:
vmImage: 'windows-latest'
variables:
- group: [REDACTED]
- name: test_var
value: firstval
jobs:
- job: BuildDeploy
displayName: "REDACTED"
steps:
- script: echo "test_var = $(test_var)"
displayName: first variable pass
- bash: echo "##vso[task.setvariable variable=test_var]secondValue"
displayName: set new variable value
- script: echo "test_var = $(test_var)"
displayName: second variable pass
- job: Test
displayName: "Testjob"
steps:
- script: echo "test_var=$(test_var)"
name: TestVar
displayName: 'test'
Here is a piece of code:
parameters:
- name: Scenario1
type: object
default: ['Test1','Test2','Test3','Test4']
- name: Scenario2
type: object
default: ['Test5','Test6']
jobs:
- job: Test_Run
pool:
vmImage: 'ubuntu-latest'
steps:
- template: Test.yml
parameters:
tests: ${{ parameters['Scenario1'] }}
For now the part:
tests: ${{ parameters['Scenario1'] }} is hardcoded. I would like to have something like this to be able to pick a scenario:
parameters:
- name: Scenario1
type: object
default: ['Test1','Test2','Test3','Test4']
- name: Scenario2
type: object
default: ['Test5','Test6']
jobs:
- job: Test_Run
pool:
vmImage: 'ubuntu-latest'
steps:
- template: Test.yml
parameters:
tests: ${{ parameters[$(Scenario)] }}
I would like to pass a $(Scenario) variable from Azure pipeline, but I do not know how to insert a variable inside ${{xxx}}. :|
You are looking for using object types. Would be something like
- name: Scenarios
type: object
default:
- ScenarioName: 'Scenario1'
Tests: ['Test1','Test2','Test3','Test4']
- ScenarioName: 'Scenario2'
Tests: ['Test5','Test6']
Then it would be called like:
- ${{ each Scenario in parameters.Scenarios}} :
- template: test.yml
parameters:
ScenarioName: ${{ Scenario.ScenarioName}}
ScenarioTests: ${{ Scenario.Tests}}
I want to introduce a for loop in a workflow that consists of 2 individual tasks. The second will be dependent on the first. Each one should use different templates. The second should iterate with {{item}}. For each iteration I want to know if the default is to execute only the second task or it will re-execute the whole flow?
To repeat the second step only, use withItems/withParameter (there is no withArtifact, though you can get the same behavior with data). These loops repeat the specific step they are mentioned in for the specified items/parameter only.
- name: create-resources
inputs:
paramet`enter code here`ers:
- name: env
- name: giturl
- name: resources
- name: awssecret
dag:
tasks:
- name: resource
template: resource-create
arguments:
parameters:
- name: env
value: "{{inputs.parameters.env}}"
- name: giturl
value: "{{inputs.parameters.giturl}}"
- name: resource
value: "{{item}}"
- name: awssecret
value: "{{inputs.parameters.awssecret}}"
withParam: "{{inputs.parameters.resources}}"
############# For parallel execution use steps ##############
steps:
- - name: resource
template: resource-create
arguments:
parameters:
- name: env
value: "{{inputs.parameters.env}}"
- name: giturl
value: "{{inputs.parameters.giturl}}"
- name: resource
value: "{{item}}"
- name: awssecret
value: "{{inputs.parameters.awssecret}}"
withParam: "{{inputs.parameters.resources}}"