You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DevOps流水线启用VM Trusted Launch时间歇性报LinkedAuthorizationFailed错误

问题:Azure DevOps流水线中Update-AzVM间歇性触发LinkedAuthorizationFailed错误

场景概述

通过Azure DevOps流水线,先用Terraform在Azure创建虚拟机,接着在同一流水线内执行PowerShell脚本:停止VM、修改配置启用Trusted Launch后重启。多数情况下流程正常,但间歇性在Update-AzVM步骤失败。

流水线代码片段

pool:
  vmImage: windows-latest

jobs:
  - job: Build
    steps:
    - task: TerraformInstaller@0
      displayName: Install terraform
      inputs:
        terraformVersion: latest

    - task: AzureCLI@2
      displayName: Create build resources (VM, ...)
      name: terraform_apply
      inputs:
        azureSubscription: <redacted>
        scriptType: pscore
        scriptLocation: inlineScript
        inlineScript: |
          terraform init
          if ($LASTEXITCODE -ne 0) {
            throw "Terraform init failed with exitcode $LASTEXITCODE"
          }

          $buildId = "$(Build.BuildNumber)" -replace "\.","-"
          $prefix = "pipeline-" + $buildId
          Write-Host "Prefix is $prefix"
          Write-Host "##vso[task.setvariable variable=resourcePrefix]$prefix"

          $Env:TF_VAR_prefix="pipeline-$buildId"
          $imageUrl = "https://<redacted>.blob.core.windows.net/<redacted>.vhd"

          Write-Host "image_uri is $imageUrl"
          $Env:TF_VAR_image_uri="$imageUrl"

          $diskSize = "${{ parameters.diskSize }}"

          Write-Host "disk_size is $diskSize"
          $Env:TF_VAR_disk_size="$diskSize"

          terraform apply -auto-approve
          if ($LASTEXITCODE -ne 0) {
            throw "Terraform apply failed with exitcode $LASTEXITCODE"
          }

          # Export the IP address for usage in later tasks
          $ip = (terraform output -json | ConvertFrom-Json).vm_ip.value
          Write-Host "##vso[task.setvariable variable=vmIp]$ip"
          Write-Host "IP is: $ip"

          $vmName = (terraform output -json | ConvertFrom-Json).vm_name.value
          Write-Host "##vso[task.setvariable variable=vmName]$vmName"
          Write-Host "VM name is: $vmName"

  - task: AzurePowerShell@5
      displayName: Enabling trusted launch
      inputs:
        azureSubscription: <redacted>
        ScriptType: InlineScript
        azurePowerShellVersion: LatestVersion
        Inline: |
          Stop-AzVM -ResourceGroupName "<redacted>" -Name "$(vmName)" -Force

          $vm = Get-AzVM -ResourceGroupName "<redacted>" -VMName "$(vmName)"
          $vm | Update-AzVM -SecurityType TrustedLaunch -EnableSecureBoot $true -EnableVtpm $true

          Start-AzVM -ResourceGroupName "<redacted>" -Name "$(vmName)"

间歇性错误信息

The client '<redacted>' with object id '<redacted>' has permission to perform action 'Microsoft.Compute/virtualMachines/write' on scope '/subscriptions/<redacted>/resourceGroups/<redacted>/providers/Microsoft.Compute/virtualMachines/<redacted>'; however, it does not have permission to perform action(s) 'Microsoft.ManagedIdentity/userAssignedIdentities/assign/action' on the linked scope(s) '/subscriptions/<redacted>/resourceGroups/Built-In-Identity-RG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/Built-In-Identity-westeurope' (respectively) or the linked scope(s) are invalid.
ErrorCode: LinkedAuthorizationFailed
StatusCode: 403
ReasonPhrase: Forbidden

解决方案建议

1. 补充服务主体的托管标识权限

错误核心是流水线使用的服务主体,对Built-In-Identity-RG资源组下的用户分配托管标识,缺少Microsoft.ManagedIdentity/userAssignedIdentities/assign/action权限:

  • 直接给服务主体在该托管标识资源(或所属资源组)上分配Managed Identity Operator角色,该角色包含所需的分配权限;
  • 或者通过自定义RBAC角色,仅授予Microsoft.ManagedIdentity/userAssignedIdentities/assign/action单个权限,遵循最小权限原则。

2. 添加操作等待与重试逻辑

间歇性失败大概率是Azure资源状态同步延迟导致:Terraform创建VM后,关联的托管标识或RBAC权限未完全生效,就执行了Update操作:

  • 等待VM完全停止:在Stop-AzVM后,添加循环等待,确认VM进入deallocated状态再执行后续操作:
    Stop-AzVM -ResourceGroupName "<redacted>" -Name "$(vmName)" -Force
    # 等待VM完全停止
    do {
        Start-Sleep -Seconds 10
        $vmStatus = Get-AzVM -ResourceGroupName "<redacted>" -Name "$(vmName)" -Status
    } while ($vmStatus.Statuses[1].Code -ne 'PowerState/deallocated')
    
  • 给Update-AzVM添加重试:用循环包裹Update操作,失败后重试几次:
    $retryCount = 3
    $retryInterval = 15
    $success = $false
    for ($i=1; $i -le $retryCount; $i++) {
        try {
            $vm | Update-AzVM -SecurityType TrustedLaunch -EnableSecureBoot $true -EnableVtpm $true
            $success = $true
            break
        }
        catch {
            Write-Warning "Update attempt $i failed: $_"
            Start-Sleep -Seconds $retryInterval
        }
    }
    if (-not $success) {
        throw "Failed to update VM after $retryCount attempts"
    }
    

3. 统一资源组变量,避免硬编码

当前PowerShell脚本中的资源组是硬编码值,建议改为从Terraform输出或流水线变量获取,比如在Terraform中输出资源组名称,然后在流水线中传递,减少人为错误。

4. 检查Terraform创建的VM配置

确认Terraform创建VM时,是否自动关联了用户分配托管标识。如果是,可考虑在Terraform阶段就配置Trusted Launch,避免后续PowerShell修改,减少跨步骤的状态同步问题。


内容的提问来源于stack exchange,提问作者Thomas Ljungberg Kristensen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 06:54:50