【发布时间】:2020-07-03 16:03:38
【问题描述】:
我在 azure devops 服务中有一个多阶段的完整 yaml 管道。不同的阶段包括构建阶段、开发阶段(将 azure 资源部署到 azure 资源组)和 UAT 阶段(将 azure 资源部署到不同的资源组)。一切都很好。但是我需要使用模板,因为我想重用这些步骤。将步骤移至模板后,开发阶段继续工作,但 UAT 阶段给出授权错误。值得一提的是,dev 和 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: printAllVariables@1
- task: CopyFiles@2
inputs:
SourceFolder: '$(System.DefaultWorkingDirectory)'
Contents: 'ARM-Templates/**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
- task: PowerShell@2
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: DownloadBuildArtifacts@0
inputs:
buildType: 'specific'
project: '530cfd4b-51b8-4237-b2fa-f296a4cba29d'
pipeline: '30'
buildVersionToDownload: 'latest'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)/CommonTasks'
- task: DownloadBuildArtifacts@0
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)/SftpConnection'
- task: FileTransform@1
displayName: 'ARMT SFTP Connection - Parameters File Transform '
inputs:
folderPath: '$(System.ArtifactsDirectory)/SftpConnection/drop'
fileType: json
targetFiles: 'ARM-Templates/parameters.json'
- task: AzurePowerShell@4
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: AzureResourceGroupDeployment@2
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: DownloadBuildArtifacts@0
inputs:
buildType: 'specific'
project: '530cfd4b-51b8-4237-b2fa-f296a4cba29d'
pipeline: '30'
buildVersionToDownload: 'latest'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)/CommonTasks'
- task: DownloadBuildArtifacts@0
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)/SftpConnection'
- task: FileTransform@1
displayName: 'ARMT SFTP Connection - Parameters File Transform '
inputs:
folderPath: '$(System.ArtifactsDirectory)/SftpConnection/drop'
fileType: json
targetFiles: 'ARM-Templates/parameters.json'
- task: AzurePowerShell@4
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: AzureResourceGroupDeployment@2
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: printAllVariables@1
- task: CopyFiles@2
inputs:
SourceFolder: '$(System.DefaultWorkingDirectory)'
Contents: 'ARM-Templates/**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
- task: PowerShell@2
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: DownloadBuildArtifacts@0
inputs:
buildType: 'specific'
project: '530cfd4b-51b8-4237-b2fa-f296a4cba29d'
pipeline: '30'
buildVersionToDownload: 'latest'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)/CommonTasks'
- task: DownloadBuildArtifacts@0
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)/SftpConnection'
- template: YamlTemplate/azure-resource-deploy.yml@templates
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: DownloadBuildArtifacts@0
inputs:
buildType: 'specific'
project: '530cfd4b-51b8-4237-b2fa-f296a4cba29d'
pipeline: '30'
buildVersionToDownload: 'latest'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)/CommonTasks'
- task: DownloadBuildArtifacts@0
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)/SftpConnection'
- template: YamlTemplate/azure-resource-deploy.yml@templates
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-parameter-file-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: FileTransform@1
displayName: ${{parameters.transformStepDisplayName}}
inputs:
folderPath: ${{parameters.folderPath}}
fileType: json
targetFiles: ${{parameters.targetFile}}
(天蓝色资源检查.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: AzurePowerShell@4
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: AzureResourceGroupDeployment@2
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 中服务主体的权限有关。确保您在管道中使用正确的服务连接,并且服务主体已获得充分授权。
-
是的,服务主体在订阅中具有贡献者角色。当我不使用 yaml 模板文件时,这再次完美运行。为什么将步骤移动到模板文件会有什么不同?
-
不会。您确定它显示的客户端 ID 属于您期望的服务主体吗?你的 YAML 是什么样的?
-
我更新了帖子以显示带有和不带有模板的 yaml 代码。我不确定如何找到它在错误中显示的客户端 ID。我怎样才能找到它?
-
包括所有 YAML,包括你创建的模板。
标签: azure azure-devops azure-yaml-pipelines