1
votes

I have a YAML template that handles deployment of several Azure Functions:

parameters:
  azureSubscription: ''
  services: []

steps:
- ${{ each service in parameters.services }}:
  - task: AzureRmWebAppDeployment@4
    displayName: Deploy Azure Function ${{ service.name }}
    inputs:
      ConnectionType: 'AzureRM'
      azureSubscription: '${{ parameters.azureSubscription }}'
      appType: 'functionApp'
      WebAppName: '${{ service.webAppName }}'
      packageForLinux: '${{ service.packagePath }}'

In the main pipeline, I'm calling the template very simply passing an array of functions and the required parameters:

# Deploy Azure Functions
- template: ../Deploy/deploy-azure-functions.yml
  parameters:
    azureSubscription: 'XXX'
    services:
    - service: 
      name: 'Func 1'
      webAppName: 'func1'
      packagePath: 'Func1.zip'
    - service: 
      name: 'Func 2'
      webAppName: 'func2'
      packagePath: 'Function2.zip'

Now everything works as expected because all the functions needs to be deployed. However, I have the need to exclude Function 2 when a certain condition (that I understand only at runtime) is valid.

Let me make an example. Suppose just before deploying all the Azure Functions I have a PowerShell scripts that creates the variable:

- pwsh: | 
    # Do some calculation and determine whether to proceed with deployment
    Write-Host "##vso[task.setvariable variable=DEPLOY;]$deploymentEnabled"
  displayName: 'Set dynamic variable'

Now I have into the variable $(DEPLOY) a value (true of false) that indicates whether I can deploy or not a certain function. I would then expect to have the value passed in the template, like:

# Deploy Azure Functions
- template: ../Deploy/deploy-azure-functions.yml
  parameters:
    azureSubscription: 'XXX'
    services:
    - service: 
      name: 'Func 1'
      webAppName: 'func1'
      packagePath: 'Func1.zip'
    - service: 
      name: 'Func 2'
      webAppName: 'func2'
      packagePath: 'Function2.zip'
      deploy: $(DEPLOY)

Please notice that the deploy parameter was added just for Function 2, because I need to always deploy Function 1 and I want this to be an optional parameter, so that when it's omitted, then the deployment will occur.

Now I have to change the template to something like:

- ${{ each service in parameters.services }}:
 - task: AzureRmWebAppDeployment@4
   displayName: Deploy Azure Function ${{ service.name }}
   condition: or(eq('${{ service.deploy }}', ''), eq('${{ service.deploy }}', 'true')) 
   inputs:
     ConnectionType: 'AzureRM'
     azureSubscription: '${{ parameters.azureSubscription }}'
     appType: 'functionApp'
     WebAppName: '${{ service.webAppName }}'
     packageForLinux: '${{ service.packagePath }}'

Notice the condition: if value for parameter 'deploy' is not set or the value is 'true', then the deployment should happen, otherwise it should be skipped.

While I though to be quite straightforward, it is not, because the variable is not evaluated and it's passed as a string (I guess the template evaluation comes first). Is there a way to make this working?

1
Have you tried using the runtime expression syntax $[variables.var] for your variable? You can find a description of the various syntaxas hereConnell.O'Donnell
Yes, but it seems it's not getting evaluated unfortunatelyxTuMiOx

1 Answers

2
votes

As a workaround, we could use condition in the field deploy and then pass the parameters to template.

Sample script:

YAML build definition:

trigger: none

variables:
    test: "true"
steps:
  - pwsh: | 
      # Do some calculation and determine whether to proceed with deployment
      Write-Host "##vso[task.setvariable variable=DEPLOY;]true"
    displayName: 'Set dynamic variable'

  - template: Template.yml
    parameters:
      azureSubscription: 'XXX'
      services:
      - service: 
        name: 'Func 1'
        webAppName: 'func1'
        packagePath: 'Func1.zip'
      - service: 
        name: 'Func 2'
        webAppName: 'func2'
        packagePath: 'Function2.zip'
        deploy: eq(variables['DEPLOY'], true)

Template.yml

parameters:
  azureSubscription: ''
  services: []
steps:
- ${{ each service in parameters.services }}:
  - task: PowerShell@2
    displayName: ${{ service.name }}
    condition: ${{ service.deploy }}
    inputs:
      targetType: 'inline'
      script: |
        Write-Host "The value of DEPLOY is: " $($env:DEPLOY)
        #Write-Host "The value of DEPLOY is: " ${{ service.deploy }}

Result:

Set the DEPLOY value to true:

enter image description here

Set the DEPLOY value to false:

enter image description here