Azure DevOps Build Pipeline Resource Authorization Issue

Viewed 22

I am trying to build a pipeline that build, deploy and configure an Azure Function. So far so now I have the following yaml:

trigger:
- none

pr:
- none

pool:
  vmImage: "windows-latest"

variables:
  group: my_variable_group //here I have the target Azure Function Information (Subscription, Resource Group, Function Name, etc.)
  buildPath: $(System.DefaultWorkingDirectory)/pipelines/maintenance
  buildConfiguration: 'Release'
  dotNetVersion: '6.0.x'
  output: 'output'
  project: '**/project.csproj'
  
steps:

- task: UseDotNet@2
  displayName: 'Use .NET Core SDK'
  inputs:
    packageType: 'sdk'
    version: $(dotNetVersion)

- task: DotNetCoreCLI@2
  displayName: 'Restore Packages'
  inputs:
    command: restore
    projects: $(project)

- script: |
    dotnet build --configuration $(buildConfiguration)
  workingDirectory: $(buildPath)
  displayName: 'Build'

- task: DotNetCoreCLI@2
  displayName: 'Publish'
  inputs:
    command: publish
    arguments: '--configuration $(buildConfiguration) --output $(output)'
    projects: $(buildPath)
    publishWebProjects: false
    modifyOutputPath: false
    zipAfterPublish: false

- task: ArchiveFiles@2
  displayName: 'Archive files'
  inputs:
    rootFolderOrFile: $(System.DefaultWorkingDirectory)/$(output)
    includeRootFolder: false
    archiveFile: $(System.DefaultWorkingDirectory)/build.zip

- task: PublishBuildArtifacts@1
  displayName: 'Publish Build Artifacts'
  inputs:
    PathtoPublish: $(System.DefaultWorkingDirectory)/build.zip
    artifactName: 'content-maintenance'
//Issues starts here. For this steps on I use the variables inside my_variable_group
- task: AzureFunctionApp@1
  displayName: 'Azure Function App Deploy'
  inputs:
    azureSubscription: $(Subscription)
    appType: functionApp
    appName: $(AppName)
    deployToSlotOrASE: true
    resourceGroupName: $(ResourceGroup)
    slotName: $(Slot)
    deploymentMethod: zipDeploy

- task: AzureAppServiceSettings@1
  displayName: 'Azure App Service Settings'
  inputs:
    azureSubscription: $(Subscription)
    appName: $(AppName)
    resourceGroupName: $(ResourceGroup)
    slotName: $(Slot)
    appSettings: |
     [
       {
         "name": "AzureWebJobsStorage",
         "value": $(AzureWebJobsStorage),
         "slotSetting": false
       },
       {
         "name": "VaultUri",
         "value": $(VaultUri),
         "slotSetting": false
       },
       {
         "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
         "value": $(WEBSITE_CONTENTAZUREFILECONNECTIONSTRING),
         "slotSetting": false
       },
       {
         "name": "WEBSITE_CONTENTSHARE",
         "value": $(WEBSITE_CONTENTSHARE),
         "slotSetting": false
       }
     ]

When I try to run my pipeline, the following error is displayed

There was a resource authorization issue: "The pipeline is not valid. Job Job: Step AzureFunctionApp input azureSubscription references service connection $(Subscription) 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 Job: Step AzureAppServiceSettings input ConnectedServiceName references service connection $(Subscription) 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."

I already check and both, my_variable_group and the service connection where the variable $(Subscription) have my pipeline added on Pipeline permissions section. Do you know how should I address this? I know that the part that is failing is:

- task: AzureFunctionApp@1
  displayName: 'Azure Function App Deploy'
  inputs:
    azureSubscription: $(Subscription) <-- here

I am assuming that I can use a variable to set subscription instead of hardcoding it into the yaml.

1 Answers

It happens due to how the Azure DevOps expand the pipelines during execution:

https://learn.microsoft.com/en-us/azure/devops/pipelines/process/runs?view=azure-devops#process-the-pipeline

It also answers another common issue: why can't I use variables to resolve service connection / environment names? Resources are authorized before a stage can start running, so stage- and job-level variables aren't available. Pipeline-level variables can be used, but only those explicitly included in the pipeline. Variable groups are themselves a resource subject to authorization, so their data is likewise not available when checking resource authorization.

To workaround it, I create a local variable in the pipeline with the same name, $(Subscription) in your case, and hard code the service connection of the lowest environment (usually dev), so the validation will pass. Be sure to add the local variable before the variable groups, so in a later stage, when the pipeline expands the variable groups will be replaced by the correct value.

Related