1

I need to set azureSubscription property for AzurePowerShell@5 task.

The value depends on EnvName parameter, which is as follows:

- name: EnvName
  displayName: Environment Name
  type: string
  default: dev
  values:
  - dev
  - test
  - uat
  - prod

I want to do this in PowerShell in Job #1 in SetVariables task:

if (${{ parameters.EnvName }} -eq "prod") {
    echo "##vso[task.setvariable variable=AzureSubscription;isOutput=true]Production Subscription"
} else {
    echo "##vso[task.setvariable variable=AzureSubscription;isOutput=true]Non-Production Subscription"
} 

And then assign the value to the task in Job #2:

  - job: job2
    dependsOn: job1
    variables:
      AzureSubscription: $[ dependencies.job1.outputs['SetVariables.AzureSubscription'] ]
    steps:
    - task: AzurePowerShell@5
      inputs:
        azureSubscription: '$(AzureSubscription)'

Unfortunately, this doesn't work. When executing the pipeline, I immediately get following error:

There was a resource authorization issue: "The pipeline is not valid. Job job2: Step AzurePowerShell input ConnectedServiceNameARM references service connection $(AzureSubscription) which could not be found. The service connection does not exist or has not been authorized for use. For authorization details, refer to https://aka.ms/yamlauthz. Job job2: Step AzurePowerShell input ConnectedServiceNameARM references service connection $(AzureSubscription) which could not be found. The service connection does not exist or has not been authorized for use. For authorization details, refer to https://aka.ms/yamlauthz."

If I create AzureSubscription as a parameter instead of a runtime-computed variable, then everything works fine. But I would prefer not to, as the pipeline user shouldn't need to set its value, and doesn't need to know which value is correct.

It seems that azureSubscription property of AzurePowerShell@5 task is evaluated during compile-time. So I need to evaluate my variable (or parameter, or whatever) during compile-time too.

The only solution I came up with is to determine which job to run based on EnvName parameter, something like this:

- ${{ if eq(parameters.EnvName, 'prod') }}: 
  - script: echo run AzurePowerShell@5 with Production Subscription
- ${{ if ne(parameters.EnvName, 'prod') }}: 
  - script: echo run AzurePowerShell@5 with Non-Production Subscription

But in that case I have 2 almost identical task declarations, this complicates my YAML quite a bit.

Another solution would be to use PowerShell@2 task instead of AzurePowerShell@5. That I would also rather not do.

Is there a better way to achieve my goal?

Bogdan Verbenets
  • 25,686
  • 13
  • 66
  • 119
  • 1
    I guess a better way is not to code such behavior in the pipeline. Instead, I would create multiple pipelines (let's say, one per environment) and just hammer the values as variables. You can opt for templates or a generic yaml if you want to avoid too much manual labor. – Evandro Pomatti Dec 04 '21 at 04:51
  • 1
    You can just create a variables template file and load the correct one by specifying `- template: variables.${{ parameters.environment }}.yml`, depending on how you name your files. – Daniel Mann Dec 04 '21 at 14:41
  • 1
    Please check this https://stackoverflow.com/questions/68037078/azuredevops-can-we-pass-dynamic-value-as-service-connection-in-yaml – Krzysztof Madej Dec 06 '21 at 01:07

0 Answers0