Deploy to App Service using Azure Pipelines

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

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 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.

Prerequisites

Create your pipeline

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.

Add the Azure Web App task

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

    Screenshot of Azure web app task.

  2. Select Azure Resource Manager for the Connection type and choose your Azure subscription. Make sure to Authorize your connection.

  3. Select Web App on Linux and enter your azureSubscription, appName, and package. Your complete YAML should look like this.

    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: '<Azure service connection>'
        appType: 'webAppLinux'
        appName: '<Name of web app>'
        package: '$(System.DefaultWorkingDirectory)/**/*.zip'
    
    • azureSubscription: your Azure subscription.
    • 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.

Now you're ready to read through the rest of this article to learn some of the more common changes that people make to customize an Azure Web App deployment.

Use the Azure Web App task

The Azure Web App Deploy task 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 allows you to modify configuration settings inside web packages and XML parameters files.

Deploy a Web Deploy package

To deploy a .zip Web Deploy package (for example, from an ASP.NET web app) to an Azure Web App, add the following snippet to your azure-pipelines.yml file:

- task: AzureWebApp@1
  inputs:
    azureSubscription: '<Azure service connection>'
    appName: '<Name of web app>'
    package: $(System.DefaultWorkingDirectory)/**/*.zip    
  • azureSubscription: your Azure subscription.
  • 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.

The snippet assumes that the build steps in your YAML file produce the zip archive in the $(System.DefaultWorkingDirectory) folder on your agent.

For information on Azure service connections, see the following section.

Deploy a .NET app

if you're building a .NET Core app, use the following snipped to deploy the build to an app.

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: '<Azure service connection>'
    appType: 'webAppLinux'
    appName: '<Name of web app>'
    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.

Use a service connection

To deploy to Azure App Service, you'll need to use an Azure Resource Manager service connection. The Azure service connection stores the credentials to connect from Azure Pipelines or Azure DevOps Server to Azure.

Learn more about Azure Resource Manager service connections. If your service connection isn't working as expected, see Troubleshooting service connections.

You'll need an Azure service connection for the AzureWebApp task. The Azure service connection stores the credentials to connect from Azure Pipelines to Azure. See Create an Azure service connection.

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 AzureRmWebAppDeployment task:

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

Deploy to a slot

You can configure the Azure Web App to have multiple slots. Slots allow you to safely deploy your app and test it before making it available to your customers.

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

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

- task: AzureAppServiceManage@0
  inputs:
    azureSubscription: '<Azure service connection>'
    appType: webAppLinux
    WebAppName: '<name of web app>'
    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.

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: '<Azure service connection>'
      appType: <app type>
      appName: '<name of test stage web app>'
      deployToSlotOrASE: true
      resourceGroupName: <resource 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: '<Azure service connection>'
      appType: <app type>
      appName: '<name of test stage web app>'
      resourceGroupName: <resource group name>
      package: '$(Pipeline.Workspace)/**/*.zip'

Make configuration changes

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

App settings can also be resolved from Key Vault using Key Vault references.

For ASP.NET and ASP.NET Core developers, setting app settings in App Service are like setting them in <appSettings> in Web.config. You might want to apply a specific configuration for your web app target before deploying to it. This is useful when you deploy the same build to multiple web apps in a pipeline. For example, if 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.

Azure App Service Deploy task allows users to modify configuration settings in configuration files (*.config files) inside web packages and XML parameters files (parameters.xml), based on the stage name specified.

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.

Variable substitution

The following snippet shows an example of variable substitution:

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

Deploying conditionally

To do this in YAML, you can use one of these 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: '<Azure service connection>'
    appName: '<name of web app>'

To learn more about conditions, see Specify conditions.

(Classic) Deploy a release pipeline

You can use a release pipeline to pick up the artifacts published by your build and then deploy them to your Azure web site.

  1. Do one of the following to start creating a release pipeline:

    • If you've just completed a CI build, choose the link (for example, Build 20170815.1) to open the build summary. Then choose Release to start a new release pipeline that's automatically linked to the build pipeline.

    • Open the Releases tab in Azure Pipelines, open the + dropdown in the list of release pipelines, and choose Create release pipeline.

  2. The easiest way to create a release pipeline is to use a template. If you're deploying a Node.js app, select the Deploy Node.js App to Azure App Service template. Otherwise, select the Azure App Service Deployment template. Then choose Apply.

    Note

    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. If you created your new release pipeline from a build summary, check that the build pipeline and artifact is shown in the Artifacts section on the Pipeline tab. If you created a new release pipeline from the Releases tab, choose the + Add link and select your build artifact.

  4. Choose the Continuous deployment icon in the Artifacts section, check that the continuous deployment trigger is enabled, and add a filter to include the main branch.

    Note

    Continuous deployment isn't enabled by default when you create a new release pipeline from the Releases tab.

  5. Open the Tasks tab and, with Stage 1 selected, configure the task property variables as follows:

    • Azure Subscription: Select a connection from the list under Available Azure Service Connections or create a more restricted permissions connection to your Azure subscription. If you're using Azure Pipelines and if you see an Authorize button next to the input, select it to authorize Azure Pipelines to connect to your Azure subscription. If you're using TFS or if you don't see the desired Azure subscription in the list of subscriptions, see Azure Resource Manager service connection to manually set up the connection.

    • App Service Name: Select the name of the web app from your subscription.

    Note

    Some settings for the tasks may have been automatically defined as stage variables when you created a release pipeline from a template. These settings cannot be modified in the task settings; instead you must select the parent stage item in order to edit these settings.

  6. Save the release pipeline.

Create a release to deploy your app

You're now ready to create a release, which means to run the release pipeline with the artifacts produced by a specific build. This will result in deploying the build:

  1. Choose + Release and select Create a release.

  2. In the Create a new release panel, check that the artifact version you want to use is selected and choose Create.

  3. Choose the release link in the information bar message. For example: "Release Release-1 has been created".

  4. In the pipeline view, choose the status link in the stages of the pipeline to see the logs and agent output.

  5. After the release is complete, navigate to your site running in Azure using the Web App URL http://{web_app_name}.azurewebsites.net, and verify its contents.

Next steps