У меня есть многоэтапный полный конвейер yaml в сервисах Azure DevOps. Различные этапы состоят из этапа сборки, этапа разработки (развертывание ресурсов Azure в группе ресурсов Azure) и этапа UAT (развертывание ресурсов Azure в другой группе ресурсов). Все отлично работает. Однако мне нужно было использовать шаблоны, потому что я хочу повторно использовать шаги. После перемещения шагов в шаблон этап разработки продолжает работать, но этап UAT выдает ошибку авторизации. Стоит отметить, что на этапах разработки и uat используются разные сервисные соединения, нацеленные на разные подписки. Но почему это будет работать, если я не использую шаблоны и просто перемещаю шаги в файл шаблона, и это не работает. Это известная ошибка?
Это ошибка, которую я получаю при использовании шаблонного подхода:
| The client ‘9e5cc21a-bb38-46b9-a16a-289fbbf9c8b9’ with object | id ‘9e5cc21a-bb38-46b9-a16a-289fbbf9c8b9’ does not have | authorization to perform action | ‘Microsoft.Resources/subscriptions/resourceGroups/resources/read’ over scope ‘/subscriptions/7041f5ba-1040-4989-8e48-497b3b826d01/resourceGroups/Resource-Group-Test-A’ or the scope is invalid. If access was recently granted, please refresh your credentials. StatusCode: 403 ReasonPhrase: Forbidden OperationID : 464f577e-6617-4bed-9a14-1f7487b5f209
Это конвейер без использования шаблонов (отлично работает!).
# Starter pipeline # Start with a minimal pipeline that you can customize to build and deploy your code. # Add steps that build, run tests, deploy, and more: # https://aka.ms/yaml trigger: — master variables: — group: ‘Dev ARMT SFTP Connection’ resources: repositories: — repository: templates type: git name: CommonTasks stages: — stage: Build jobs: — job: Build pool: vmImage: ‘ubuntu-latest’ steps: — task: [email protected] — task: [email protected] inputs: SourceFolder: ‘$(System.DefaultWorkingDirectory)’ Contents: ‘ARM-Templates/**’ TargetFolder: ‘$(Build.ArtifactStagingDirectory)’ — task: [email protected] inputs: PathtoPublish: ‘$(Build.ArtifactStagingDirectory)’ ArtifactName: ‘drop’ publishLocation: ‘Container’ — task: [email protected] inputs: targetType: ‘inline’ script: | # Write your PowerShell commands here. Write-Host «Build Completed…» $workingdir = «$(Build.ArtifactStagingDirectory)» Write-Host $workingdir $fcontent = Get-ChildItem -Path $workingdir Write-Host $fcontent — stage: Dev jobs: — job: Dev pool: vmImage: ‘ubuntu-latest’ steps: — task: [email protected] inputs: buildType: ‘specific’ project: ‘530cfd4b-51b8-4237-b2fa-f296a4cba29d’ pipeline: ’30’ buildVersionToDownload: ‘latest’ downloadType: ‘single’ artifactName: ‘drop’ downloadPath: ‘$(System.ArtifactsDirectory)/CommonTasks’ — task: [email protected] inputs: buildType: ‘current’ downloadType: ‘single’ artifactName: ‘drop’ downloadPath: ‘$(System.ArtifactsDirectory)/SftpConnection’ — task: [email protected] displayName: ‘ARMT SFTP Connection — Parameters File Transform ‘ inputs: folderPath: ‘$(System.ArtifactsDirectory)/SftpConnection/drop’ fileType: json targetFiles: ‘ARM-Templates/parameters.json’ — task: [email protected] displayName: ‘ARMT SFTP Connection — Check Resource Existance’ inputs: azureSubscription: ‘Starwood-DT-DEV-ServiceConnection’ ScriptPath: ‘$(System.ArtifactsDirectory)/CommonTasks/drop/AzurePowerShell/ResourceExistance.ps1’ ScriptArguments: ‘-resourceGroupName Starwood-DT-DEV -resourceName $(parameters.sftp_name.value)’ azurePowerShellVersion: LatestVersion — task: [email protected] displayName: ‘ARMT SFTP Connection — Deploy’ inputs: azureSubscription: ‘Starwood-DT-DEV-ServiceConnection’ resourceGroupName: ‘Starwood-DT-DEV’ location: ‘East US’ csmFile: ‘$(System.ArtifactsDirectory)/SftpConnection/drop/ARM-Templates/template.json’ csmParametersFile: ‘$(System.ArtifactsDirectory)/SftpConnection/drop/ARM-Templates/parameters.json’ condition: eq(variables[‘deployresource’],’true’) — stage: GroupATest jobs: — job: GroupATest pool: vmImage: ‘ubuntu-latest’ steps: — task: [email protected] inputs: buildType: ‘specific’ project: ‘530cfd4b-51b8-4237-b2fa-f296a4cba29d’ pipeline: ’30’ buildVersionToDownload: ‘latest’ downloadType: ‘single’ artifactName: ‘drop’ downloadPath: ‘$(System.ArtifactsDirectory)/CommonTasks’ — task: [email protected] inputs: buildType: ‘current’ downloadType: ‘single’ artifactName: ‘drop’ downloadPath: ‘$(System.ArtifactsDirectory)/SftpConnection’ — task: [email protected] displayName: ‘ARMT SFTP Connection — Parameters File Transform ‘ inputs: folderPath: ‘$(System.ArtifactsDirectory)/SftpConnection/drop’ fileType: json targetFiles: ‘ARM-Templates/parameters.json’ — task: [email protected] displayName: ‘ARMT SFTP Connection — Check Resource Existance’ inputs: azureSubscription: ‘Resource-Group-Test-A’ ScriptPath: ‘$(System.ArtifactsDirectory)/CommonTasks/drop/AzurePowerShell/ResourceExistance.ps1’ ScriptArguments: ‘-resourceGroupName Resouce-Group-Test-A -resourceName $(parameters.sftp_name.value)’ azurePowerShellVersion: LatestVersion — task: [email protected] displayName: ‘ARMT SFTP Connection — Deploy’ inputs: azureSubscription: ‘Resource-Group-Test-A’ resourceGroupName: ‘Resouce-Group-Test-A’ location: ‘East US’ csmFile: ‘$(System.ArtifactsDirectory)/SftpConnection/drop/ARM-Templates/template.json’ csmParametersFile: ‘$(System.ArtifactsDirectory)/SftpConnection/drop/ARM-Templates/parameters.json’ condition: eq(variables[‘deployresource’],’true’)
При переходе к шаблону шагов (тогда я получаю сообщение об ошибке):
# Starter pipeline # Start with a minimal pipeline that you can customize to build and deploy your code. # Add steps that build, run tests, deploy, and more: # https://aka.ms/yaml trigger: — master resources: repositories: — repository: templates type: git name: CommonTasks stages: — stage: Build jobs: — job: Build pool: vmImage: ‘ubuntu-latest’ steps: — task: [email protected] — task: [email protected] inputs: SourceFolder: ‘$(System.DefaultWorkingDirectory)’ Contents: ‘ARM-Templates/**’ TargetFolder: ‘$(Build.ArtifactStagingDirectory)’ — task: [email protected] inputs: PathtoPublish: ‘$(Build.ArtifactStagingDirectory)’ ArtifactName: ‘drop’ publishLocation: ‘Container’ — task: [email protected] inputs: targetType: ‘inline’ script: | # Write your PowerShell commands here. Write-Host «Build Completed…» $workingdir = «$(Build.ArtifactStagingDirectory)» Write-Host $workingdir $fcontent = Get-ChildItem -Path $workingdir Write-Host $fcontent — stage: Dev variables: — group: ‘Dev ARMT SFTP Connection’ jobs: — job: Dev pool: vmImage: ‘ubuntu-latest’ steps: — task: [email protected] inputs: buildType: ‘specific’ project: ‘530cfd4b-51b8-4237-b2fa-f296a4cba29d’ pipeline: ’30’ buildVersionToDownload: ‘latest’ downloadType: ‘single’ artifactName: ‘drop’ downloadPath: ‘$(System.ArtifactsDirectory)/CommonTasks’ — task: [email protected] inputs: buildType: ‘current’ downloadType: ‘single’ artifactName: ‘drop’ downloadPath: ‘$(System.ArtifactsDirectory)/SftpConnection’ — template: YamlTemplate/[email protected] parameters: dropLocation: ‘$(System.ArtifactsDirectory)/SftpConnection/drop’ transformTargetPath: ‘ARM-Templates/parameters.json’ resourceName: $(parameters.sftp_name.value) resourceGroupName: ‘Starwood-DT-DEV’ azureServiceConnectionName: ‘Starwood-DT-DEV-ServiceConnection’ resourceLocation: ‘East US’ armtTemplateFilePath: ‘$(System.ArtifactsDirectory)/SftpConnection/drop/ARM-Templates/template.json’ armtParemeterFilePath: ‘$(System.ArtifactsDirectory)/SftpConnection/drop/ARM-Templates/parameters.json’ — stage: GroupATest variables: — group: ‘GroupA ARMT SFTP Connection’ jobs: — job: GroupATest pool: vmImage: ‘ubuntu-latest’ steps: — task: [email protected] inputs: buildType: ‘specific’ project: ‘530cfd4b-51b8-4237-b2fa-f296a4cba29d’ pipeline: ’30’ buildVersionToDownload: ‘latest’ downloadType: ‘single’ artifactName: ‘drop’ downloadPath: ‘$(System.ArtifactsDirectory)/CommonTasks’ — task: [email protected] inputs: buildType: ‘current’ downloadType: ‘single’ artifactName: ‘drop’ downloadPath: ‘$(System.ArtifactsDirectory)/SftpConnection’ — template: YamlTemplate/[email protected] parameters: dropLocation: ‘$(System.ArtifactsDirectory)/SftpConnection/drop’ transformTargetPath: ‘ARM-Templates/parameters.json’ resourceName: $(parameters.sftp_name.value) resourceGroupName: ‘Resource-Group-Test-A’ azureServiceConnectionName: ‘Resource-Group-Test-A’ resourceLocation: ‘East US’ armtTemplateFilePath: ‘$(System.ArtifactsDirectory)/SftpConnection/drop/ARM-Templates/template.json’ armtParemeterFilePath: ‘$(System.ArtifactsDirectory)/SftpConnection/drop/ARM-Templates/parameters.json’
Это структура шаблона Родительский шаблон — (azure-resource-deploy.yml):
parameters: — name: dropLocation type: string displayName: ‘Artifact path to drop location’ default: » — name: transformTargetPath type: string default: » — name: resourceName type: string default: » — name: resourceGroupName type: string default: » — name: azureServiceConnectionName type: string default: » — name: resourceLocation type: string default: » — name: armtTemplateFilePath type: string default: » — name: armtParemeterFilePath type: string default: » steps: — template: armt-parameter-file-transform.yml parameters: transformStepDisplayName: » folderPath: ${{parameters.dropLocation}} targetFile: ${{parameters.transformTargetPath}} — template: azure-resource-check.yml parameters: resourceName: ${{parameters.resourceName}} resourceGroupName: ${{parameters.resourceGroupName}} azureServiceConnectionName: ${{parameters.azureServiceConnectionName}} — template: armt-deploy.yml parameters: resourceName: ${{parameters.resourceName}} resourceGroupName: ${{parameters.resourceGroupName}} resourceLocation: ${{parameters.resourceLocation}} azureServiceConnectionName: ${{parameters.azureServiceConnectionName}} templateFilePath: ${{parameters.armtTemplateFilePath}} parametersFilePath: ${{parameters.armtParemeterFilePath}}
Шаблоны, на которые ссылается родительский элемент:
(файл-параметр-armt-transform.yml)
parameters: — name: transformStepDisplayName type: string displayName: ‘Display name for this step’ default: » — name: folderPath type: string displayName: ‘Path to drop location’ default: » — name: targetFile type: string displayName: ‘Path to paremeter file relative to drop location.’ default: » steps: — task: [email protected] displayName: ${{parameters.transformStepDisplayName}} inputs: folderPath: ${{parameters.folderPath}} fileType: json targetFiles: ${{parameters.targetFile}}
(лазурный-ресурс-check.yml)
parameters: — name: resourceName type: string — name: resourceGroupName type: string — name: azureServiceConnectionName type: string steps: — script: echo Echo -resourceGroupName ${{ parameters.resourceGroupName }} -resourceName ${{ parameters.resourceName }} — task: [email protected] displayName: ‘${{ parameters.resourceName }} — Checking Resource Existance’ inputs: azureSubscription: ‘${{ parameters.azureServiceConnectionName }}’ ScriptPath: ‘$(System.ArtifactsDirectory)/CommonTasks/drop/AzurePowerShell/ResourceExistance.ps1’ ScriptArguments: ‘-resourceGroupName ${{ parameters.resourceGroupName }} -resourceName ${{ parameters.resourceName }}’ azurePowerShellVersion: LatestVersion
(armt-deploy.yml)
parameters: — name: resourceName type: string — name: resourceGroupName type: string — name: resourceLocation type: string — name: azureServiceConnectionName type: string — name: templateFilePath type: string — name: parametersFilePath type: string steps: — task: [email protected] displayName: ‘ARMT Deploy — ${{parameters.resourceName}}’ inputs: azureSubscription: ${{parameters.azureServiceConnectionName}} resourceGroupName: ${{parameters.resourceGroupName}} location: ${{parameters.resourceLocation}} csmFile: ${{parameters.templateFilePath}} csmParametersFile: ${{parameters.parametersFilePath}} condition: eq(variables[‘deployresource’],’true’)
Эта ошибка не имеет ничего общего с конвейером и полностью связана с разрешениями субъекта-службы в Azure. Убедитесь, что вы используете правильное сервисное соединение в своем конвейере, и что субъект-сервис имеет соответствующие полномочия. — person user2503480 schedule 03.07.2020
Да, у субъекта-службы есть роль участника в подписке. Опять же, это отлично работает, когда я не использую файл шаблона yaml. Почему перемещение шагов в файл шаблона имеет какое-то значение? — person user2503480 schedule 03.07.2020
Это не так. Вы уверены, что отображаемый идентификатор клиента принадлежит субъекту службы, которого вы ожидаете? Как выглядит ваш YAML? — person user2503480 schedule 03.07.2020
Я обновил сообщение, чтобы показать код yaml с шаблоном и без него. Я не уверен, как найти идентификатор клиента, отображаемый в сообщении об ошибке. Как я могу это узнать? — person user2503480 schedule 03.07.2020
Включите весь YAML, включая созданный вами шаблон. — person user2503480 schedule 03.07.2020
Я добавил полный код. Включая структуру шаблона — person user2503480 schedule 03.07.2020
@DanielMann — также неудачный шаг — это шаг PowerShell, который я использую, чтобы проверить, существует ли ресурс, который просто вызывает Get-AzResource -ResourceGroupName $ resourceGroupName -Name $ resourceName. Но даже если я исключу этот шаг и просто выполню следующую задачу (развертывание шаблона руки), я также получу сообщение об ошибке. Как-то при перемещении шагов в шаблоны теряется авторизация … очень странно. — person user2503480 schedule 03.07.2020
@ user2503480 Если вы создадите стадию UAT до стадии Dev, каков результат? — person user2503480 schedule 06.07.2020
Попробуйте использовать одинарные кавычки там, где в конце вы используете свой параметр. У меня есть точное решение, как и у вас, и единственное отличие, которое я вижу: ‘$ {{parameters.azureServiceConnectionName}}’ вместо: $ {{parameters.azureServiceConnectionName}} — person user2503480 schedule 06.07.2020
@ CeceDong-MSFT .. При смене ступеней получаю те же результаты. Даже я полностью удалил стадию разработки. Оставил это с одним этапом и тем же результатом — person user2503480 schedule 06.07.2020
@Repcak Это изменение не имело никакого значения — person user2503480 schedule 06.07.2020
Пробуем еще кое-что. Если я удалю этап проверки наличия ресурсов AzurePowerShell @ 4, и оставлю только этап развертывания шаблона ARM (AzureResourceGroupDeployment @ 2). Я все еще получаю ошибку авторизации, но с таким описанием: ## [error] Ознакомьтесь с руководством по устранению неполадок, чтобы узнать, решена ли ваша проблема: docs.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/ ## [ошибка] Не удалось проверить статус группы ресурсов. Ошибка: {statusCode: 403}. — person user2503480 schedule 06.07.2020
Источник: