Skip to content

Latest commit

 

History

History
458 lines (316 loc) · 19.5 KB

deploy-azure-pipelines.md

File metadata and controls

458 lines (316 loc) · 19.5 KB
title description ms.topic ms.date ms.author ms.manager ms.custom author
Configure CI/CD with Azure Pipelines
Learn how to deploy your code to Azure App Service from a CI/CD pipeline with Azure Pipelines.
article
06/04/2024
jukullam
mijacobs
devops-pipelines-deploy
cephalin

Deploy to App Service using Azure Pipelines

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

[!INCLUDE regionalization-note]

Use Azure Pipelines to automatically deploy your web app to Azure App Service on every successful build. Azure Pipelines lets you build, test, and deploy with continuous integration (CI) and continuous delivery (CD) using Azure DevOps.

YAML pipelines are defined using a YAML file in your repository. A step is the smallest building block of a pipeline and can be a script or task (prepackaged script). Learn about the key concepts and components that make up a pipeline.

You'll use the Azure Web App task (AzureWebApp) to deploy to Azure App Service in your pipeline. For more complicated scenarios such as needing to use XML parameters in your deploy, you can use the Azure App Service deploy task (AzureRmWebAppDeployment).

Prerequisites

1. Create a pipeline for your stack

The code examples in this section assume you're deploying an ASP.NET web app. You can adapt the instructions for other frameworks.

Learn more about Azure Pipelines ecosystem support.

  1. Sign in to your Azure DevOps organization and navigate to your project.

  2. Go to Pipelines, and then select New Pipeline.

  3. When prompted, select the location of your source code: either Azure Repos Git or GitHub.

    You might be redirected to GitHub to sign in. If so, enter your GitHub credentials.

  4. When the list of repositories appears, select your repository.

  5. You might be redirected to GitHub to install the Azure Pipelines app. If so, select Approve & install.

  6. When the Configure tab appears, select ASP.NET Core.

  7. When your new pipeline appears, take a look at the YAML to see what it does. When you're ready, select Save and run.

To get started:

  1. Create a pipeline and select the ASP.NET Core template. This selection automatically adds the tasks required to build the code in the sample repository.

  2. Save the pipeline and queue a build to see it in action.

    The ASP.NET Core pipeline template publishes the deployment ZIP file as an Azure artifact for the deployment task later.


2. Add the deployment task

  1. Click the end of the YAML file, then select Show assistant.'

  2. Use the Task assistant to add the Azure Web App task.

    :::image type="content" source="media/deploy-azure-pipelines/azure-web-app-task.png" alt-text="Screenshot of Azure web app task.":::

    Alternatively, you can add the Azure App Service deploy (AzureRmWebAppDeployment) task.

  3. Choose your Azure subscription. Make sure to Authorize your connection. The authorization creates the required service connection.

  4. Select the App type, App name, and Runtime stack based on your App Service app. Your complete YAML should look similar to the following code.

    variables:
      buildConfiguration: 'Release'
    
    steps:
    - 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: Name of the authorized service connection to your Azure subscription.
    • appName: Name of your existing app.
    • package: File path to the package or a folder containing your app service contents. Wildcards are supported.

To get started:

  1. Create a release pipeline by selecting Releases from the left menu and select New pipeline.

  2. Select the Azure App Service deployment template for your stage. This automatically adds the necessary tasks.

    [!NOTE] If you're deploying a Node.js app to App Service on Windows, select the Deploy Node.js App to Azure App Service template. The only difference between these templates is that Node.js template configures the task to generate a web.config file containing a parameter that starts the iisnode service.

  3. To link this release pipeline to the Azure artifact from the previous step, select Add an artifact > Build.

  4. In Source (build pipeline), select the build pipeline you created in the previous section, then select Add.

  5. Save the release pipeline and create a release to see it in action.


Example: Deploy a .NET app

To deploy a .zip web package (for example, from an ASP.NET web app) to an Azure Web App, use the following snippet to deploy the build to an app.

variables:
  buildConfiguration: 'Release'

steps:
- 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: your Azure subscription.
  • appType: your Web App type.
  • appName: the name of your existing app service.
  • package: the file path to the package or a folder containing your app service contents. Wildcards are supported.

For classic pipelines, it's the easiest to define build and release stages in separate pages (Pipelines and Releases, respectively). In general, you:

  • In the Pipelines page, build and test your app by using the template of your choice, such as ASP.NET Core, Node.js with Grunt, Maven, or others, and publish an artifact.
  • In the Release page, use the generic Azure App Service deployment template to deploy the artifact.

There may be templates for specific programming languages to choose from.


Example: deploy to a virtual application

By default, your deployment happens to the root application in the Azure Web App. You can deploy to a specific virtual application by using the VirtualApplication property of the Azure App Service deploy (AzureRmWebAppDeployment) task:

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

By default, your deployment happens to the root application in the Azure Web App. If you want to deploy to a specific virtual application, enter its name in the Virtual Application property of the Azure App Service deploy task.


Example: Deploy to a slot

The following example shows how to deploy to a staging slot, and then swap to a production slot:

- 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: your Azure subscription.
  • appType: (optional) Use webAppLinux to deploy to a Web App on Linux.
  • appName: the name of your existing app service.
  • deployToSlotOrASE: Boolean. Deploy to an existing deployment slot or Azure App Service Environment.
  • resourceGroupName: Name of the resource group. Required if deployToSlotOrASE is true.
  • slotName: Name of the slot, which defaults to production. Required if deployToSlotOrASE is true.
  • package: the file path to the package or a folder containing your app service contents. Wildcards are supported.
  • SourceSlot: Slot sent to production when SwapWithProduction is true.
  • SwapWithProduction: Boolean. Swap the traffic of source slot with production.

Use the option Deploy to Slot or App Service Environment in the Azure Web App task to specify the slot to deploy to. To swap the slots, use the Azure App Service manage task.


Example: Deploy to multiple web apps

You can use jobs in your YAML file to set up a pipeline of deployments. By using jobs, you can control the order of deployment to multiple web apps.

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'

If you want to deploy to multiple web apps, add stages to your release pipeline. You can control the order of deployment. To learn more, see Stages.


Example: Make variable substitutions

For most language stacks, app settings and connection strings can be set as environment variables at runtime.

But there are other reasons you would want to make variable substitutions to your Web.config. In this example, your Web.config file contains a connection string named connectionString. You can change its value before deploying to each web app. You can do this either by applying a Web.config transformation or by substituting variables in your Web.config file.

The following snippet shows an example of variable substitution by using the Azure App Service Deploy (AzureRmWebAppDeployment) task:

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

To change connectionString by using variable substitution:

  1. Create a release pipeline with two stages.
  2. Link the artifact of the release to the build that produces the web package.
  3. Define connectionString as a variable in each of the stages. Set the appropriate value.
  4. Select the XML variable substitution option under File Transforms and Variable Substitution Options for the Azure App Service Deploy task.

Example: Deploy conditionally

To do this in YAML, you can use one of the following techniques:

  • Isolate the deployment steps into a separate job, and add a condition to that job.
  • Add a condition to the step.

The following example shows how to use step conditions to deploy only builds that originate from the main branch:

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

To learn more about conditions, see Specify conditions.

In your release pipeline, you can implement various checks and conditions to control the deployment:

  • Set branch filters to configure the continuous deployment trigger on the artifact of the release pipeline.
  • Set pre-deployment approvals as a precondition for deployment to a stage.
  • Configure gates as a precondition for deployment to a stage.
  • Specify conditions for a task to run.

To learn more, see Release, branch, and stage triggers, Release deployment control using approvals, Release deployment control using gates, and Specify conditions for running a task.


Example: deploy using Web Deploy

The Azure App Service deploy (AzureRmWebAppDeployment) task can deploy to App Service using Web Deploy.

trigger:
- main

pool:
  vmImage: windows-latest

variables:
  buildConfiguration: 'Release'

steps:
- 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'

In the release pipeline, assuming you're using the Azure App Service deployment template:

  1. Select the Tasks tab, then select Deploy Azure App Service. This is the AzureRmWebAppDeployment task.

  2. In the dialog, make sure that Connection type is set to Azure Resource Manager.

  3. In the dialog, expand Additional Deployment Options and select Select deployment method. Make sure that Web Deploy is selected as the deployment method.

  4. Save the release pipeline.

Note

With the AzureRmWebAppDeployment@3 and AzureRmWebAppDeployment@4 tasks, you should use the Azure Resource Manager connection type, or AzureRM, when deploying with Web Deploy. It uses publishing profiles for deployment when basic authentication is enabled for your app, but it uses the more secure Entra ID authentication when basic authentication is disabled.


Frequently asked questions

What's the difference between the AzureWebApp and AzureRmWebAppDeployment tasks?

The Azure Web App task (AzureWebApp) is the simplest way to deploy to an Azure Web App. By default, your deployment happens to the root application in the Azure Web App.

The Azure App Service Deploy task (AzureRmWebAppDeployment) can handle more custom scenarios, such as:

Note

File transforms and variable substitution are also supported by the separate File Transform task for use in Azure Pipelines. You can use the File Transform task to apply file transformations and variable substitutions on any configuration and parameters files.

I get the message "Invalid App Service package or folder path provided."

In YAML pipelines, depending on your pipeline, there may be a mismatch between where your built web package is saved and where the deploy task is looking for it. For example, the AzureWebApp task picks up the web package for deployment. For example, the AzureWebApp task looks in $(System.DefaultWorkingDirectory)/**/*.zip. If the web package is deposited elsewhere, modify the value of package.

I get the message "Publish using webdeploy options are supported only when using Windows agent."

This error occurs in the AzureRmWebAppDeployment task when you configure the task to deploy using Web Deploy, but your agent isn't running Windows. Verify that your YAML has something similar to the following code:

pool:
  vmImage: windows-latest

Web Deploy doesn't work when I disable basic authentication

For troubleshooting information on getting Microsoft Entra ID authentication to work with the AzureRmWebAppDeployment task, see I can't Web Deploy to my Azure App Service using Microsoft Entra ID authentication from my Windows agent

Next steps