I have a pipeline that will clean, convert a VM to an image, and delete all of the resources. I would like to use that same pipeline to delete VMs without capturing an image. I can make all of the stages conditional, but when I end up with no stages that have no conditions. I keep seeing that the accepted solution to this problem is to make the dependsOn conditional as shown below. the deleteVM parameter is a boolean.
Parameters:
- name: deleteVM
displayName: "just delete it"
type: boolean
default: false
- stages:
- stage: firstStage
dependsOn: []
condition: eq('${{ parameters.deleteVM }}', 'false')
jobs:
- job: deallocateVM
- stage: secondStage
${{ if eq(parameters.deleteVM, 'false') }}:
dependsOn: firstStage
${{ if eq(parameters.deleteVM, 'true') }}:
dependsOn: []
The issue is that when I do this, and try to run the pipeline with the second condition being true, it will error when parsing the pipeline: "YAML: ‘dependsOn’ is already defined."
P.S. I’ve looked at the following and they imply that the way I’m doing it is the "right" way:
- Azure pipeline – Stage condition dependson
- Azure Pipeline – Stage with Multiple depends on with if condition
Based on the comments and answers below, I have tried:
Parameters:
- name: deleteVM
displayName: "just delete it"
type: boolean
default: false
- stages:
- stage: firstStage
dependsOn: []
condition: eq('${{ parameters.deleteVM }}', 'false')
jobs:
- job: deallocateVM
- stage: secondStage
${{ if eq(parameters.deleteVM, 'false') }}:
dependsOn: firstStage
${{ else }}:
dependsOn: []
Result is "Unrecognized value: ‘else’. Location at position 1 within expression: else."
I have tried to use NOT EQUALS:
Parameters:
- name: deleteVM
displayName: "just delete it"
type: boolean
default: false
- stages:
- stage: firstStage
dependsOn: []
condition: eq('${{ parameters.deleteVM }}', 'false')
jobs:
- job: deallocateVM
- stage: secondStage
${{ if eq(parameters.deleteVM, 'false') }}:
dependsOn: firstStage
${{ if ne(parameters.deleteVM, 'false') }}:
dependsOn: []
Result is that no matter if I put true or false, or what I put in the dependsOn in the first position, it skips this stage when deleteVM is true (I think it is ignoring this stage).
I have also tried creating a variable which I had some luck with:
Parameters:
- name: deleteVM
displayName: "just delete it"
type: boolean
default: false
variables:
- ${{ if eq(parameters.deleteVM, 'false') }}:
- name: dependency
value: anActualStage
- ${{ if eq(parameters.deleteVM, 'false') }}:
- name: dependency
value: '[]'
- stages:
- stage: firstStage
dependsOn: []
condition: eq('${{ parameters.deleteVM }}', 'false')
jobs:
- job: deallocateVM
- stage:
- stage: secondStage
dependsOn: ${{ variables.dependency }}
Result is that this will always do the opposite of what I want. no matter if I set the default value to true or false, when I set deleteVM:true, it shows "firstStage" as a dependency, and if I set deleteVM:false, it shows NO DEPENDENCY.
I get that this is interpreted at compile time and this is somewhat the behavior I’m looking for because toggling the deleteVM checkbox switches between having a dependency or not, however, it is always the wrong selection. If I continue with it doing the opposite thing I want, I can see that the secondstage runs without any dependencies (but I have to make the opposite selection of what I want). I would rather not update the verbiage to just say the opposite of what is really going on in the background and I have little confidence in this being consistent across different runs so I don’t trust this enough to merge what I have for people to use.
As someone mentioned in the comment, I am using Azure Stack Hub which has very dated software and hardware limitations…
2
Answers
Instead of 2 if statements, use if/else. Or simply leave out the else altogether, since you’re setting the depends on to an empty list.
@4c74356b41´s answer about using if-else is probably your best bet.
The way yaml works is that the
dependsOn
in your example is only really added to the "compiled" yaml file if yourif
statement resolves to true. Thus, there must be something wrong with your variables, as it looks like both of your logical statements resolves to true. I cannot really see why as it looks impossible by your example, but that is the only way I can see you getting the error you are seeing.