使用 Azure Resource Manager 服務連線 連線 至 Azure

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

您可以使用 Azure Resource Manager 服務連線,透過服務主體驗證或透過 Azure 受控服務識別來連線到 Azure 資源。 如果您使用 Resource Manager 服務連線,您可以使用管線來部署至 Azure 資源,例如 Azure App 服務 應用程式,而不需要每次驗證。

您可以使用 Azure Resource Manager 服務連線來連線到 Azure 有多個選項:

  • 具有工作負載身分識別同盟的服務主體或受控識別
  • 具備密碼的服務主體
  • 代理程式指派的受控識別

若要瞭解其他類型的連線,以及建立和使用連線的一般資訊,請參閱 組建和版本的服務連線。

建立使用工作負載身分識別同盟的 Azure Resource Manager 服務連線

工作負載身分識別同盟會使用 OpenID 連線 (OIDC) 向 Microsoft Entra 保護的資源進行驗證,而不需使用秘密。

如果下列所有專案都適用於您的案例,建議您使用此方法:

  • 您有 Azure 訂用帳戶的擁有者角色。
  • 您未連線到 Azure StackAzure Government 雲端
  • 您使用的任何 Marketplace 擴充功能工作都會更新,以支援工作負載身分識別同盟。

建立新的工作負載身分識別同盟服務連線

  1. 在 Azure DevOps 專案中,移至 [項目設定>服務連線]。

    如需詳細資訊,請參閱 開啟項目設定

  2. 選取 [ 新增服務連線],然後選取 [Azure Resource Manager]。

    顯示選擇工作負載身分識別服務連線類型的螢幕快照。

  3. 選取 [工作負載身分識別同盟][自動]。

    顯示選取工作負載身分識別服務連線類型的螢幕快照。

  4. 指定下列參數:

    參數 描述
    訂用帳戶 選取現有的 Azure 訂閱。 如果沒有出現 Azure 訂用帳戶或實例,請參閱 針對 Azure Resource Manager 服務連線進行疑難解答。
    資源群組 保留空白,讓使用者存取訂用帳戶內定義的所有資源。 若要限制使用者存取資源,請輸入資源組名。 然後,使用者只能存取針對該資源群組定義的資源。
    服務連線名稱 必要。 您用來在工作屬性中參考此服務連線的名稱。 不是 Azure 訂用帳戶的名稱。
  5. 建立新的服務連線之後,複製連線名稱,並將它貼到您的程式代碼中做為的值 azureSubscription

  6. 若要部署至特定的 Azure 資源,工作需要更多有關該資源的數據。 移至 Azure 入口網站 中的資源,然後將數據複製到您的程式代碼中。 例如,若要部署 Web 應用程式,請複製 Azure App 服務 應用程式的名稱,並將它貼到您的程式代碼中做為的值WebAppName

將現有的 Azure Resource Manager 服務連線轉換為使用工作負載身分識別同盟

您可以快速轉換現有的 Azure Resource Manager 服務連線,以使用工作負載身分識別同盟進行驗證,而不是服務主體。 如果您的服務連線符合下列需求,您可以在 Azure DevOps 中使用服務連線轉換工具:

  • Azure DevOps 原本已建立服務連線。 如果您手動建立服務連線,就無法使用服務連線轉換工具來轉換服務連線,因為 Azure DevOps 沒有修改自己的認證的許可權。
  • 只有一個專案會使用服務連線。 您無法轉換跨 專案服務 連線

若要轉換服務連線:

  1. 在 Azure DevOps 專案中,移至 [項目設定>服務連線]。

    如需詳細資訊,請參閱 開啟項目設定

  2. 選取您想要轉換成使用工作負載身分識別的服務連線。

  3. 選取轉換

    顯示針對同盟認證選取 [轉換] 的螢幕快照。

    如果您有具有過期密碼的現有服務主體認證,您會看到不同的轉換選項。

    顯示當您有過期憑證時,要轉換成使用同盟認證的選項的螢幕快照。

  4. 再次選取 [轉換 ] 以確認您想要建立新的服務連線。

    轉換可能需要幾分鐘的時間。 如果您想要還原連線,您必須在七天內還原連線。

使用腳本轉換多個 Azure Resource Manager 服務連線

使用腳本一次更新多個服務連線,現在使用工作負載身分識別同盟進行驗證。

此範例 PowerShell 腳稿需要兩個參數:Azure DevOps 組織(例如: https://dev.azure.com/fabrikam-tailspin) 和 Azure DevOps 專案(範例: Space game web agent。 然後,腳本會擷取 Azure DevOps 專案和組織的相關服務連線。 系統會要求您確認您想要轉換未使用工作負載身分識別同盟的每個相關聯服務連線。 如果您確認,腳本會使用 Azure DevOps REST API 來更新每個服務連線,以使用工作負載身分識別同盟。 腳本需要 PowerShell 7.3 或更新版本Azure CLI 才能執行。 將腳本儲存至 .ps1 檔案,並使用Powershell 7加以執行。

#!/usr/bin/env pwsh
<# 
.SYNOPSIS 
    Convert multiple Azure Resource Manager service connection(s) to use Workload identity federation

.LINK
    https://aka.ms/azdo-rm-workload-identity-conversion

.EXAMPLE
    ./convert_azurerm_service_connection_to_oidc_simple.ps1 -Project <project> -OrganizationUrl https://dev.azure.com/<organization>
#> 

#Requires -Version 7.3

param ( 
    [parameter(Mandatory=$true,HelpMessage="Name of the Azure DevOps Project")]
    [string]
    [ValidateNotNullOrEmpty()]
    $Project,

    [parameter(Mandatory=$true,HelpMessage="Url of the Azure DevOps Organization")]
    [uri]
    [ValidateNotNullOrEmpty()]
    $OrganizationUrl
) 
$apiVersion = "7.1"
$PSNativeCommandArgumentPassing = "Standard" 

#-----------------------------------------------------------
# Log in to Azure
$azdoResource = "499b84ac-1321-427f-aa17-267ca6975798" # application id of Azure DevOps 
az login --allow-no-subscriptions --scope ${azdoResource}/.default
$OrganizationUrl = $OrganizationUrl.ToString().Trim('/')

#-----------------------------------------------------------
# Retrieve the service connection
$getApiUrl = "${OrganizationUrl}/${Project}/_apis/serviceendpoint/endpoints?authSchemes=ServicePrincipal&type=azurerm&includeFailed=false&includeDetails=true&api-version=${apiVersion}"
az rest --resource $azdoResource -u "${getApiUrl} " -m GET --query "sort_by(value[?authorization.scheme=='ServicePrincipal' && data.creationMode=='Automatic' && !(isShared && serviceEndpointProjectReferences[0].projectReference.name!='${Project}')],&name)" -o json `
        | Tee-Object -Variable rawResponse | ConvertFrom-Json | Tee-Object -Variable serviceEndpoints | Format-List | Out-String | Write-Debug
if (!$serviceEndpoints -or ($serviceEndpoints.count-eq 0)) {
    Write-Warning "No convertible service connections found"
    exit 1
}

foreach ($serviceEndpoint in $serviceEndpoints) {
    # Prompt user to confirm conversion
    $choices = @(
        [System.Management.Automation.Host.ChoiceDescription]::new("&Convert", "Converting service connection '$($serviceEndpoint.name)'...")
        [System.Management.Automation.Host.ChoiceDescription]::new("&Skip", "Skipping service connection '$($serviceEndpoint.name)'...")
        [System.Management.Automation.Host.ChoiceDescription]::new("&Exit", "Exit script")
    )
    $prompt = $serviceEndpoint.isShared ? "Convert shared service connection '$($serviceEndpoint.name)'?" : "Convert service connection '$($serviceEndpoint.name)'?"
    $decision = $Host.UI.PromptForChoice([string]::Empty, $prompt, $choices, $serviceEndpoint.isShared ? 1 : 0)

    if ($decision -eq 0) {

        Write-Host "$($choices[$decision].HelpMessage)"
    } elseif ($decision -eq 1) {
        Write-Host "$($PSStyle.Formatting.Warning)$($choices[$decision].HelpMessage)$($PSStyle.Reset)"
        continue 
    } elseif ($decision -ge 2) {
        Write-Host "$($PSStyle.Formatting.Warning)$($choices[$decision].HelpMessage)$($PSStyle.Reset)"
        exit 
    }

    # Prepare request body
    $serviceEndpoint.authorization.scheme = "WorkloadIdentityFederation"
    $serviceEndpoint.data.PSObject.Properties.Remove('revertSchemeDeadline')
    $serviceEndpoint | ConvertTo-Json -Depth 4 | Write-Debug
    $serviceEndpoint | ConvertTo-Json -Depth 4 -Compress | Set-Variable serviceEndpointRequest
    $putApiUrl = "${OrganizationUrl}/${Project}/_apis/serviceendpoint/endpoints/$($serviceEndpoint.id)?operation=ConvertAuthenticationScheme&api-version=${apiVersion}"
    # Convert service connection
    az rest -u "${putApiUrl} " -m PUT -b $serviceEndpointRequest --headers content-type=application/json --resource $azdoResource -o json `
            | ConvertFrom-Json | Set-Variable updatedServiceEndpoint

    $updatedServiceEndpoint | ConvertTo-Json -Depth 4 | Write-Debug
    if (!$updatedServiceEndpoint) {
        Write-Debug "Empty response"
        Write-Error "Failed to convert service connection '$($serviceEndpoint.name)'"
        exit 1
    }
    Write-Host "Successfully converted service connection '$($serviceEndpoint.name)'"
}

還原使用服務主體秘密的現有 Azure Resource Manager 服務連線

您可以使用其秘密還原已轉換的自動服務連線七天。 七天后,手動建立新的秘密。

如果您手動建立和轉換服務連線,就無法使用服務連線轉換工具來還原服務連線,因為 Azure DevOps 沒有修改自己的認證的許可權。

若要還原服務連線:

  1. 在 Azure DevOps 專案中,移至 [管線>服務連線]。

  2. 選取要還原的現有服務連線。

  3. 選取 [ 還原轉換至原始配置]。

    顯示選取同盟認證的還原的螢幕快照。

  4. 再次選取 [ 還原 ] 以確認您的選擇。

建立使用服務主體秘密的 Azure Resource Manager 服務連線

如果下列所有專案都適用於您的案例,建議您使用此方法:

  • 您已以 Azure Pipelines 組織和 Azure 訂用帳戶的擁有者身分登入。
  • 您不需要進一步限制使用者透過服務連線存取的 Azure 資源許可權。
  • 您未連線到 Azure StackAzure Government 雲端
  • 您未從 Azure DevOps Server 2019 或舊版 Team Foundation Server 進行連線。

若要建立服務連線:

  1. 在 Azure DevOps 專案中,移至 [項目設定>服務連線]。

    在 Team Foundation Server 中,選取頂端功能表欄中的 設定 圖示,以移至 [服務] 頁面。

    如需詳細資訊,請參閱 開啟項目設定

  2. 選取 [ 新增服務連線],然後選取 [Azure Resource Manager]。

    顯示選擇服務連線類型的螢幕快照。

  3. 輸入或選取下列參數:

    參數 描述
    連線名稱 必要。 您用來在工作屬性中參考此服務連線的名稱。 不是 Azure 訂用帳戶的名稱。
    範圍層級 選取 [訂用帳戶] 或 [管理群組]。 管理群組 是可協助您跨多個訂用帳戶管理存取、原則和合規性的容器。
    訂用帳戶 如果您針對範圍選取 [ 用帳戶],請選取現有的 Azure 訂用帳戶。 如果沒有出現 Azure 訂用帳戶或實例,請參閱 針對 Azure Resource Manager 服務連線進行疑難解答。
    管理群組 如果您針對範圍選取 [管理群組 ],請選取現有的 Azure 管理群組。 如需詳細資訊,請參閱 建立管理群組
    資源群組 保留空白,讓使用者存取訂用帳戶內定義的所有資源。 若要限制使用者存取資源,請輸入資源組名。 然後,使用者只能存取針對該資源群組定義的資源。
  4. 建立新的服務連線之後:

    • 如果您使用傳統編輯器,請選取您在管線的 Azure 訂 用帳戶設定中指派的連線名稱。
    • 如果您使用 YAML 檔案,請將連線名稱複製到程式代碼中作為的值 azureSubscription
  5. 若要部署到特定的 Azure 資源,請將資源的詳細資訊新增至工作:

    • 如果您使用傳統編輯器,請選取要新增至工作的數據。 例如,選取 App Service 名稱。
    • 如果您使用 YAML 檔案,請移至 Azure 入口網站 中的資源。 複製您需要的數據,並貼到您的工作程式代碼中。 例如,若要部署 Web 應用程式,請複製 App Service 應用程式的名稱,並將其貼上為工作 YAML 中的 值 WebAppName

注意

當您遵循此方法時,Azure DevOps 會使用 Microsoft Entra ID 連線,並使用有效三個月的秘密建立應用程式註冊。 當服務連線即將到期時,Microsoft Entra ID 會顯示此提示: 憑證或密碼即將到期。建立新的 。 在此案例中,您必須重新整理服務連線。

若要重新整理服務連線,請在 Azure DevOps 入口網站中編輯連線,然後選取 [ 驗證]。 儲存編輯之後,服務聯機會再有三個月有效。

我們建議您使用工作負載身分識別同盟,而不是建立秘密。 如果您使用工作負載身分識別同盟,則不需要輪替秘密,而應用程式註冊會維護其預期用途。 若要開始使用工作負載身分識別同盟,請移至服務連線詳細數據頁面,然後選取 [ 轉換]。 服務聯機會轉換成使用工作負載身分識別同盟,而不是秘密。 如需詳細資訊,請參閱 將現有的 Azure Resource Manager 服務連線轉換為使用工作負載身分識別同盟

如需詳細資訊,請參閱 針對 Azure Resource Manager 服務連線進行疑難解答。

如果您有使用這種方法的問題(例如下拉式清單中未顯示的訂用帳戶),或如果您想要進一步限制用戶權力,您可以改為使用 服務主體具有受控服務識別的虛擬機。

建立使用現有服務主體的 Azure Resource Manager 服務連線

  1. 如果您想要使用預先定義的一組訪問許可權,且尚未為此目的定義服務主體,請遵循下列其中一個教學課程來建立新的服務主體:

  2. 在 Azure DevOps 專案中,移至 [項目設定>服務連線]。

    在 Team Foundation Server 中,選取頂端功能表欄中的 設定 圖示,以移至 [服務] 頁面。

    如需詳細資訊,請參閱 開啟項目設定

  3. 選取 [ 新增服務連線],然後選取 [Azure Resource Manager]。

    顯示選擇服務連線類型的螢幕快照。

  4. 選取 [ 服務主體(手動)] 選項,然後輸入服務主體詳細數據。

    顯示開啟服務對話框完整版本的螢幕快照。

  5. 如需 連線 名稱,請輸入用來參考此服務連線的顯示名稱。

  6. 針對 [環境],選取環境名稱 (Azure CloudAzure StackAzure Government Cloud)。

  7. 如果您 選取 Azure 雲端,請輸入環境 URL。 針對 Azure Stack,環境 URL 類似 https://management.local.azurestack.external

  8. 針對 [ 範圍層級],選取連線的範圍:

    • 如果您選取 [ 訂用帳戶],請選取現有的 Azure 訂用帳戶。 如果沒有出現 Azure 訂用帳戶或實例,請參閱 針對 Azure Resource Manager 服務連線進行疑難解答。
    • 如果您選取 [ 管理群組],請選取現有的 Azure 管理群組。 如需詳細資訊,請參閱 建立管理群組
  9. 在 [Azure 訂用帳戶] 對話框中,輸入下列服務主體的相關信息:

    • 訂用帳戶識別碼
    • 訂用帳戶名稱
    • 服務主體識別碼
    • 服務主體用戶端密鑰,或者,如果您選取 [憑證],請輸入 *.pem 檔案的憑證和私鑰區段的內容。
    • 租用戶識別碼

    您可以下載並執行 Azure PowerShell 腳本來取得此資訊。 出現提示時,請輸入您的訂用帳戶名稱、密碼、角色(選擇性),以及雲端類型,例如 Azure 雲端(預設值)、Azure Stack 或 Azure Government Cloud。

  10. 選取 [ 驗證連線 ] 以驗證您輸入的設定。

  11. 建立新的服務連線之後:

    • 如果您在 UI 中使用服務連線,請選取您在管線的 Azure 訂 用帳戶設定中指派的連線名稱。
    • 如果您在 YAML 檔案中使用服務連線,請複製連線名稱,並將它貼到程式碼中作為的值 azureSubscription
  12. 如有必要,請修改服務主體以公開適當的許可權。

    如需使用服務主體進行驗證的詳細資訊,請參閱 使用角色型訪問控制來管理 Azure 訂用帳戶資源的 存取,或部落格文章 使用 Visual Studio 中的服務主體將 Azure 資源群組部署自動化。

如需詳細資訊,請參閱 針對 Azure Resource Manager 服務連線進行疑難解答。

建立 Azure Resource Manager 服務連線至使用受控服務識別的 VM

注意

若要使用受控服務識別進行驗證,您必須在 Azure 虛擬機 (VM) 上使用自我裝載代理程式。

您可以將 Azure VM 型代理程式設定為在 Microsoft Entra ID 中使用 Azure 受控服務識別 。 在此案例中,您會使用系統指派的身分識別(服務主體)將 Azure VM 型代理程式存取權授與支援 Microsoft Entra ID 的任何 Azure 資源,例如 Azure 金鑰保存庫 實例,而不是將認證保存在 Azure DevOps 中以進行連線。

  1. 在 Azure DevOps 專案中,移至 [項目設定>服務連線]。

    在 Team Foundation Server 中,選取頂端功能表欄中的 設定 圖示,以移至 [服務] 頁面。

    如需詳細資訊,請參閱 開啟項目設定

  2. 選取 [ 新增服務連線],然後選取 [Azure Resource Manager]。

    顯示選擇服務連線類型的螢幕快照。

  3. 選取 [ 受控識別驗證 ] 選項。

    顯示移至受控服務識別設定的螢幕快照。

  4. 如需 連線 名稱,請輸入當您參考此服務連線時要使用的顯示名稱。

  5. 針對 [環境],選取環境名稱 (Azure CloudAzure StackAzure Government Cloud)。

  6. 在 [連線] 對話框中,輸入您訂用帳戶中的下列值:

    • 訂用帳戶識別碼
    • 訂用帳戶名稱
    • 租用戶識別碼
  7. 建立新的服務連線之後:

    • 如果您在 UI 中使用服務連線,請選取您在管線的 Azure 訂 用帳戶設定中指派的連線名稱。
    • 如果您在 YAML 檔案中使用服務連線,請將連線名稱複製到您的程式代碼中作為的值 azureSubscription
  8. 請確定 VM(代理程式)具有適當的許可權。

    例如,如果您的程式代碼需要呼叫 Azure Resource Manager,請在 Microsoft Entra ID 中使用角色型訪問控制 (RBAC) 將適當的角色指派給 VM。

    如需詳細資訊,請參閱 如何使用 Azure 資源的受控識別? 和使用 角色型訪問控制來管理 Azure 訂用帳戶資源的存取權。

如需程式的詳細資訊,請參閱 針對 Azure Resource Manager 服務連線進行疑難解答。

連線 至 Azure Government 雲端

如需連線到 Azure Government 雲端的相關信息,請參閱從 Azure Pipelines (Azure Government Cloud) 連線。

連線到 Azure Stack

如需連線到 Azure Stack 的相關信息,請參閱下列文章:

說明與支援