skip to Main Content

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:

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


  1. 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.

    - stages:
      - stage: aStage
        ${{ if eq(parameters.deleteVM, 'false') }}:
          dependsOn: anActualStage
        ${{ else }}:
          dependsOn: []
    
      - stage: aStage
        ${{ if eq(parameters.deleteVM, 'false') }}:
          dependsOn: anActualStage
    
    Login or Signup to reply.
  2. @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 your if 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search