使用 Azure Pipelines 部署至 App Service

Azure DevOps Services | Azure DevOps Server 2020 | Azure DevOps Server 2019

使用 Azure Pipelines,在每次成功建置時自動將 Web 應用程式部署至 Azure App Service。 Azure Pipelines 可讓您使用 Azure DevOps 建置、測試及部署持續整合 (CI) 與持續傳遞 (CD)。

YAML 管線是使用存放庫中的 YAML 檔案來定義。 步驟是管線最小的組建區塊,可以是指令碼或工作 (預先封裝的指令碼)。 了解構成管線的重要概念和元件

您將使用 Azure Web 應用程式工作 (AzureWebApp),來部署至管線中的 Azure App Service。 若是更複雜的情節,例如需要在部署中使用 XML 參數,您可以使用 Azure App Service 部署工作 (AzureRmWebAppDeployment)

必要條件

1.建立堆疊的管線

本節中的程式碼範例假設您要部署 ASP.NET Web 應用程式。 您可以調整指示以進行其他架構。

深入了解 Azure Pipelines 生態系統支援

  1. 登入您的 Azure DevOps 組織,然後瀏覽至您的專案。

  2. 前往 [管線],然後選取 [新增管線]

  3. 出現提示時,請選擇原始程式碼的位置:Azure Repos GitGitHub

    系統可能會將您重新導向至 GitHub 以進行登入。 若是如此,請輸入 GitHub 認證。

  4. 在存放庫清單出現時,選取您的存放庫。

  5. 系統可能會將您重新導向至 GitHub,以安裝 Azure Pipelines 應用程式。 如果發生此情況,請選取 [核准和安裝]

  6. 在 [設定] 索引標籤出現時,選取 [ASP.NET Core]

  7. 在新的管線出現時,請查看 YAML 以了解其用途。 當您準備好時,請選取 [儲存並執行]

2.新增部署工作

  1. 按一下 YAML 檔案的結尾,然後選取 [顯示助理]。'

  2. 使用工作助理來新增 Azure Web 應用程式工作。

    Screenshot of Azure web app task.

    或者,您可以新增 Azure App Service 部署 (AzureRmWebAppDeployment) 工作。

  3. 選擇 Azure 訂用帳戶。 請務必 [授權] 您的連線。 授權會建立必要的服務連線。

  4. 根據 App Service 應用程式選取 [應用程式類型]、[應用程式名稱],以及 [執行階段堆疊]。 完成的 YAML 應類似下列程式碼。

    variables:
      buildConfiguration: 'Release'
    
    steps:
    - script: dotnet build --configuration $(buildConfiguration)
      displayName: 'dotnet build $(buildConfiguration)'
    - task: DotNetCoreCLI@2
      inputs:
        command: 'publish'
        publishWebProjects: true
    - task: AzureWebApp@1
      inputs:
        azureSubscription: '<service-connection-name>'
        appType: 'webAppLinux'
        appName: '<app-name>'
        package: '$(System.DefaultWorkingDirectory)/**/*.zip'
    
    • azureSubscription:Azure 訂用帳戶的授權服務連線名稱。
    • appName:現有應用程式的名稱。
    • 套件:套件的檔案路徑或包含應用程式服務內容的資料夾。 支援萬用字元。

範例:部署 .NET 應用程式

若要將 .zip 網頁套件 (例如,從 ASP.NET Web 應用程式) 部署至 Azure Web 應用程式,請使用下列程式碼片段,將該組建部署至應用程式。

variables:
  buildConfiguration: 'Release'

steps:
- script: dotnet build --configuration $(buildConfiguration)
  displayName: 'dotnet build $(buildConfiguration)'
- task: DotNetCoreCLI@2
  inputs:
    command: 'publish'
    publishWebProjects: true
- task: AzureWebApp@1
  inputs:
    azureSubscription: '<service-connection-name>'
    appType: 'webAppLinux'
    appName: '<app-name>'
    package: '$(System.DefaultWorkingDirectory)/**/*.zip'
  • azureSubscription:您的 Azure 訂閱。
  • appType:您的 Web 應用程式類型。
  • appName:現有的應用程式服務的名稱。
  • package:封裝的檔案路徑,或包含您應用程式服務內容的資料夾。 支援萬用字元。

範例:部署至虛擬應用程式

根據預設,會在 Azure Web 應用程式中的根應用程式進行您的部署。 您可以使用 Azure App Service 部署 (AzureRmWebAppDeployment) 工作的 VirtualApplication 屬性,來部署至特定的虛擬應用程式:

- task: AzureRmWebAppDeployment@4
  inputs:
    VirtualApplication: '<name of virtual application>'

範例:部署到插槽

下列範例示範如何部署至預備位置,然後交換成生產位置:

- task: AzureWebApp@1
  inputs:
    azureSubscription: '<service-connection-name>'
    appType: webAppLinux
    appName: '<app-name>'
    deployToSlotOrASE: true
    resourceGroupName: '<name of resource group>'
    slotName: staging
    package: '$(Build.ArtifactStagingDirectory)/**/*.zip'

- task: AzureAppServiceManage@0
  inputs:
    azureSubscription: '<service-connection-name>'
    appType: webAppLinux
    WebAppName: '<app-name>'
    ResourceGroupName: '<name of resource group>'
    SourceSlot: staging
    SwapWithProduction: true
  • azureSubscription:您的 Azure 訂閱。
  • appType:(選擇性) 使用 webAppLinux 部署至 Linux 上的 Web 應用程式。
  • appName:現有的應用程式服務的名稱。
  • deployToSlotOrASE:布林值。 部署至現有的部署位置或 Azure App Service 環境。
  • resourceGroupName:資源群組的名稱。 如果 deployToSlotOrASE 為 true,則為必要項。
  • slotName:插槽名稱,預設為 production。 如果 deployToSlotOrASE 為 true,則為必要項。
  • package:封裝的檔案路徑,或包含您應用程式服務內容的資料夾。 支援萬用字元。
  • SourceSlot:當 SwapWithProduction 為 true 時,傳送至生產環境的位置。
  • SwapWithProduction:布林值。 將來源位置的流量與生產環境交換。

範例:部署至多個 Web 應用程式

您可以使用 YAML 檔案中的作業來設定部署管線。 您可以使用作業來控制部署至多個 Web 應用程式的順序。

jobs:
- job: buildandtest
  pool:
    vmImage: ubuntu-latest
 
  steps:
  # publish an artifact called drop
  - task: PublishPipelineArtifact@1
    inputs:
      targetPath: '$(Build.ArtifactStagingDirectory)' 
      artifactName: drop
  
  # deploy to Azure Web App staging
  - task: AzureWebApp@1
    inputs:
      azureSubscription: '<service-connection-name>'
      appType: <app type>
      appName: '<staging-app-name>'
      deployToSlotOrASE: true
      resourceGroupName: <group-name>
      slotName: 'staging'
      package: '$(Build.ArtifactStagingDirectory)/**/*.zip'

- job: deploy
  dependsOn: buildandtest
  condition: succeeded()

  pool: 
    vmImage: ubuntu-latest  
  
  steps:
    # download the artifact drop from the previous job
  - task: DownloadPipelineArtifact@2
    inputs:
      source: 'current'
      artifact: 'drop'
      path: '$(Pipeline.Workspace)'

  - task: AzureWebApp@1
    inputs:
      azureSubscription: '<service-connection-name>'
      appType: <app type>
      appName: '<production-app-name>'
      resourceGroupName: <group-name>
      package: '$(Pipeline.Workspace)/**/*.zip'

範例:進行變數替代

對於大部分的語言堆疊,應用程式設定連接字串可以在執行階段設定為環境變數。

但您想要對 Web.config 進行變數替代的原因不僅於此。在此範例中,Web.config 檔案包含名為 connectionString 的連接字串。 部署至每個 Web 應用程式之前,您都可以變更其值。 您可以套用 Web.config 轉換或在 Web.config 檔案中替代變數來執行此動作。

下列程式碼片段示範使用 Azure App Service 部署 (AzureRmWebAppDeployment) 工作來替代變數的範例:

jobs:
- job: test
  variables:
    connectionString: <test-stage connection string>
  steps:
  - task: AzureRmWebAppDeployment@4
    inputs:
      azureSubscription: '<Test stage Azure service connection>'
      WebAppName: '<name of test stage web app>'
      enableXmlVariableSubstitution: true

- job: prod
  dependsOn: test
  variables:
    connectionString: <prod-stage connection string>
  steps:
  - task: AzureRmWebAppDeployment@4
    inputs:
      azureSubscription: '<Prod stage Azure service connection>'
      WebAppName: '<name of prod stage web app>'
      enableXmlVariableSubstitution: true

範例:有條件地部署

若要在 YAML 中執行此動作,您可以使用下列其中一種方法:

  • 將部署步驟隔離至個別的作業,並將條件新增至該作業。
  • 將條件新增至步驟。

下列範例示範如何使用步驟條件,只部署源自主分支的組建:

- task: AzureWebApp@1
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
  inputs:
    azureSubscription: '<service-connection-name>'
    appName: '<app-name>'

如需深入了解其他條件,請參閱指定條件

範例:使用 Web Deploy 部署

Azure App Service 部署 (AzureRmWebAppDeployment) 工作可以使用 Web Deploy 部署至 App Service。

trigger:
- main

pool:
  vmImage: windows-latest

variables:
  buildConfiguration: 'Release'

steps:
- script: dotnet build --configuration $(buildConfiguration)
  displayName: 'dotnet build $(buildConfiguration)'
- task: DotNetCoreCLI@2
  inputs:
    command: 'publish'
    publishWebProjects: true
    arguments: '--configuration $(buildConfiguration)'
    zipAfterPublish: true
- task: AzureRmWebAppDeployment@4
  inputs:
    ConnectionType: 'AzureRM'
    azureSubscription: '<service-connection-name>'
    appType: 'webApp'
    WebAppName: '<app-name>'
    packageForLinux: '$(System.DefaultWorkingDirectory)/**/*.zip'
    enableCustomDeployment: true
    DeploymentType: 'webDeploy'

常見問題集

AzureWebAppAzureRmWebAppDeployment 工作的差異為何?

Azure Web 應用程式工作 (AzureWebApp) 是部署至 Azure Web 應用程式最簡單的方式。 根據預設,會在 Azure Web 應用程式中的根應用程式進行您的部署。

Azure App Service Deploy 工作 (AzureRmWebAppDeployment) 可以處理更多自訂情節,例如:

注意

個別的檔案轉換工作也支援檔案轉換和變數替代,以在 Azure Pipelines 中使用。 您可以使用檔案轉換工作,在任何組態和參數檔案上套用檔案轉換和變數替代。

我收到以下訊息「提供的 App Service 套件或資料夾路徑無效」。

視管線而定,在 YAML 管線中組建 Web 套件的儲存位置與部署工作所尋找的位置之間可能不相符。 例如,AzureWebApp 工作會挑選要進行部署的網頁套件。 例如,AzureWebApp 工作會在 $(System.DefaultWorkingDirectory)/**/*.zip 中尋找。 如果網頁套件存放在別處,請修改 package 的值。

我收到以下訊息「僅限使用 Windows 代理程式時,才可使用 webdeploy 選項進行發佈」。

當您將工作設定為使用 Web Deploy 進行部署,但代理程式未執行 Windows 時,AzureRmWebAppDeployment 工作中就會發生此錯誤。 確認 YAML 具有類似下列程式碼的內容:

pool:
  vmImage: windows-latest

當我停用基本驗證時,Web Deploy 無法運作

如需取得 Microsoft Entra ID 驗證以使用 AzureRmWebAppDeployment 工作的疑難排解資訊,請參閱我無法使用 Windows 代理程式中的 Microsoft Entra ID 驗證,透過 Web Deploy 部署至 Azure App Service

下一步