Implementación en App Service mediante Azure Pipelines

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

Use Azure Pipelines para implementar automáticamente la aplicación web en Azure App Service en cada compilación correcta. Azure Pipelines permite compilar, probar e implementar con integración continua (CI) y entrega continua (CD) mediante Azure DevOps.

Las canalizaciones de YAML se definen mediante un archivo YAML en el repositorio. Un paso es el bloque de creación más pequeño de una canalización y puede ser un script o una tarea (script empaquetado previamente). Obtenga información sobre los conceptos y componentes clave que forma una canalización.

Usará la tarea Aplicación web de Azure (AzureWebApp) para implementar en Azure App Service en la canalización. En escenarios más complicados, p. ej., si necesita usar parámetros XML en la implementación, puede usar la tarea Implementación de Azure App Service (AzureRmWebAppDeployment).

Requisitos previos

1. Creación de una canalización para su pila

En los ejemplos de código de esta sección, se supone que va a implementar una aplicación web ASP.NET. Puede adaptar las instrucciones para otros marcos.

Obtenga más información sobre la compatibilidad con el ecosistema de Azure Pipelines.

  1. Inicie sesión en su organización de Azure DevOps y vaya a su proyecto.

  2. Vaya a Canalizaciones y seleccione Nueva canalización.

  3. Cuando se le solicite, seleccione la ubicación del código fuente: Azure Repos Git o GitHub.

    Puede que se le redirija a GitHub para iniciar sesión. Si es así, escriba sus credenciales de GitHub.

  4. Cuando aparezca la lista de repositorios, seleccione el que corresponda.

  5. Es posible que se le redirija a GitHub para instalar la aplicación Azure Pipelines. Si es así, seleccione Aprobar e instalar.

  6. Cuando aparezca la pestaña Configurar, seleccione ASP.NET Core.

  7. Cuando aparezca la nueva canalización, eche un vistazo al archivo YAML para ver lo que hace. Cuando esté listo, seleccione Guardar y ejecutar.

2. Agregar la tarea de implementación

  1. Haga clic en el final del archivo YAML y seleccione Mostrar asistente.

  2. Use el Asistente de tareas para agregar la tarea Aplicación web de Azure.

    Screenshot of Azure web app task.

    También puede agregar la tarea implementación de Azure App Service (AzureRmWebAppDeployment).

  3. Elija la suscripción de Azure. Asegúrese de autorizar la conexión. La autorización crea la conexión de servicio necesaria.

  4. Seleccione el tipo de aplicación, nombre de aplicacióny runtime de pila en función de la aplicación de App Service. El código YAML completo debe tener un aspecto similar al siguiente.

    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: nombre de la conexión de servicio autorizada a la suscripción de Azure.
    • appName: nombre de la aplicación existente.
    • package: ruta de acceso del archivo al paquete o una carpeta con el contenido del servicio de aplicaciones. Se admite caracteres comodín.

Ejemplo: Implementación de una aplicación .NET

Para implementar un paquete web .zip (por ejemplo, desde una aplicación web de ASP.NET) en una aplicación web de Azure, use el siguiente fragmento de código para implementar la compilación en una aplicación.

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: su suscripción a Azure.
  • appType: el tipo de aplicación web.
  • appName: el nombre del servicio de aplicaciones existente.
  • package: la ruta de acceso del archivo al paquete o una carpeta que contiene el contenido del servicio de aplicaciones. Se admite caracteres comodín.

Ejemplo: Implementación en una aplicación virtual

De forma predeterminada, la implementación se produce en la aplicación raíz de la aplicación web de Azure. Puede implementar en una aplicación virtual específica mediante la propiedad VirtualApplication de la tarea implementación de Azure App Service (AzureRmWebAppDeployment):

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

Ejemplo: Implementación en una ranura

El siguiente ejemplo muestra cómo implementar en un espacio de ensayo y, a continuación, cambiar a un espacio de producción:

- 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: su suscripción a Azure.
  • appType: (opcional) Use webAppLinux para implementar en una aplicación web en Linux.
  • appName: el nombre del servicio de aplicaciones existente.
  • deployToSlotOrASE: valor booleano para implementar en una ranura de implementación existente o en un Azure App Service Environment.
  • resourceGroup: nombre del grupo de recursos. Es necesario si el valor de deployToSlotOrASE es true.
  • slotName: Nombre de la ranura, que el valor predeterminado es production. Es necesario si el valor de deployToSlotOrASE es true.
  • package: la ruta de acceso del archivo al paquete o una carpeta que contiene el contenido del servicio de aplicaciones. Se admite caracteres comodín.
  • SourceSlot: ranura enviada a producción cuando el valor de SwapWithProduction es true.
  • SwapWithProduction: valor booleano para intercambiar el tráfico de la ranura de origen con producción.

Ejemplo: Implementación en varias aplicaciones web

Puede usar trabajos en el archivo YAML para configurar una canalización de implementaciones. Mediante trabajos, puede controlar el orden de implementación en varias aplicaciones 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'

Ejemplo: Sustituciones de variables

En la mayoría de las pilas de lenguaje, la configuración de la aplicación y las cadenas de conexión se pueden establecer como variables de entorno en tiempo de ejecución.

Pero hay otras razones por las que puede ser útil realizar sustituciones de variables en Web.config. En este ejemplo, el archivo Web.config contiene una cadena de conexión denominada connectionString. Puede cambiar su valor antes de implementar en cada aplicación web. Para ello, puede aplicar una transformación de Web.config o sustituir las variables en el archivo Web.config.

En el fragmento de código siguiente se muestra un ejemplo de sustitución de variables mediante la tarea Implementación de 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

Ejemplo: Implementación condicional

Para hacer esto en YAML, puede usar una de estas técnicas:

  • Aísle los pasos de implementación en un trabajo independiente y agregue una condición a ese trabajo.
  • Agregue una condición al paso.

En el ejemplo siguiente se muestra cómo usar condiciones de paso para implementar solamente compilaciones que se originan en la rama principal:

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

Para más información sobre condiciones, consulte Especificación de condiciones.

Ejemplo: Implementación mediante Web Deploy

La tarea de implementación de Azure App Service (AzureRmWebAppDeployment) puede realizarse en App Service mediante Web Deploy.

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'

Preguntas más frecuentes

¿Cuál es la diferencia entre los valores AzureWebApp y AzureRmWebAppDeployment?

La tarea Azure Web App (AzureWebApp) es la manera más sencilla de implementar en una aplicación web de Azure. De forma predeterminada, la implementación se produce en la aplicación raíz de la aplicación web de Azure.

La tarea de implementación de Azure App Service (AzureRmWebAppDeployment) puede controlar escenarios más personalizados, como:

Nota:

Las transformaciones de archivos y la sustitución de variables también son compatibles con la tarea Transformación de archivos independiente para su uso en Azure Pipelines. Puede usar la tarea Transformación de archivos para aplicar transformaciones de archivo y sustituciones de variables en cualquier archivo de configuración y parámetros.

Recibo el mensaje "Se proporcionó un paquete de App Service o una ruta de acceso de carpeta no válidas".

En las canalizaciones de YAML, en función de la canalización, puede haber un error de coincidencia entre dónde se guarda el paquete web compilado y dónde se busca la tarea de implementación. Por ejemplo, la tarea AzureWebApp recoge el paquete web para la implementación. La tarea AzureWebApp busca en $(System.DefaultWorkingDirectory)/**/*.zip. Si el paquete web se deposita en otro lugar, modifique el valor de package.

Recibo el mensaje "Publicar con opciones de Web Deploy solo se admite cuando se usa el agente de Windows".

Este error se produce en la tarea azureRmWebAppDeployment al configurar la tarea para implementar mediante Web Deploy, si el agente no ejecuta Windows. Compruebe que YAML muestra algo similar al código siguiente:

pool:
  vmImage: windows-latest

Web Deploy no funciona cuando deshabilito la autenticación básica

Para obtener información sobre cómo obtener la autenticación de Microsoft Entra ID para trabajar con la tarea de AzureRmWebAppDeployment, consulte no puedo realizar usar Web Deploy en mi instancia de Azure App Service mediante la autenticación de Microsoft Entra ID desde mi agente de Windows

Pasos siguientes