Reputation: 453
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?
Upvotes: 1
Views: 6934
Reputation: 8298
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:
Set the DEPLOY value to false:
Upvotes: 3