Compartir vía


Uso de Azure Pipelines para crear e implementar una aplicación web de Python en Azure App Service

Azure DevOps Services

Use Azure Pipelines para la integración y entrega continuas (CI/CD) para crear e implementar una aplicación web de Python en Azure App Service en Linux. La canalización crea e implementa automáticamente la aplicación web de Python en App Service cada vez que hay una confirmación en el repositorio.

En este artículo aprenderá a:

  • Crear una aplicación web en Azure App Service.
  • Creación de un proyecto en Azure DevOps.
  • Conectar su proyecto de DevOps con Azure.
  • Crear una canalización específica de Python.
  • Ejecutar la canalización para crear e implementar la aplicación en la aplicación web en App Service.

Requisitos previos

Creación de un repositorio para almacenar el código de la aplicación

Bifurque el repositorio de muestra de https://github.com/Microsoft/python-sample-vscode-flask-tutorial a su cuenta de GitHub.

En el host local, clone el repositorio de GitHub. Use el comando siguiente, reemplazando <repository-url> por la dirección URL del repositorio bifurcado.

git clone <repository-url>

Prueba local de la aplicación

Cree y ejecute la aplicación de forma local para asegurarse de que funciona.

  1. Cambie a la carpeta del repositorio clonado.

    cd python-sample-vscode-flask-tutorial
    
  2. Compilar y ejecutar la aplicación

    python -m venv .env
    source .env/bin/activate
    pip install --upgrade pip
    pip install -r ./requirements.txt
    export set FLASK_APP=hello_app.webapp
    python3 -m flask run
    
  3. Para ver la aplicación, abra una ventana del navegador y vaya a http://localhost:5000. Compruebe que ve el título Visual Studio Flask Tutorial.

  4. Cuando haya terminado, cierre la ventana del navegador y detenga el servidor Flask con Ctrl+C.

Abrir una ventana de Cloud Shell

  1. Inicie sesión en Azure Portal en https://portal.azure.com.

  2. Para abrir la CLI de Azure, seleccione el botón Cloud Shell en la barra de herramientas del portal.

    Captura de pantalla del botón Azure Cloud Shell en la barra de herramientas de Azure Portal.

  3. Cloud Shell aparece en la parte inferior del explorador. Seleccione Bash en el menú desplegable.

    Captura de pantalla de Azure Cloud Shell

  4. Para disponer de más espacio para trabajar, seleccione el botón maximizar.

Creación de una aplicación web de Azure App Service

Cree la aplicación web de Azure App Service desde Cloud Shell en Azure Portal.

Sugerencia

Para pegar en Cloud Shell, use Ctrl+Mayús+V o haga clic con el botón derecho y seleccione Pegar en el menú contextual.

  1. Clone el repositorio con el siguiente comando y reemplace <repository-url> por la dirección URL del repositorio bifurcado.

    git clone <repository-url>
    
  2. Cambie el directorio a la carpeta del repositorio clonado para que el comando az webapp up reconozca la aplicación como una aplicación de Python.

    cd python-sample-vscode-flask-tutorial
    
  3. Use el comando az webapp up para aprovisionar App Service y realizar la primera implementación de la aplicación. Reemplace <your-web-app-name> por un nombre que sea único en Azure. Normalmente, se usa un nombre personal o de empresa junto con un identificador de aplicación, como <your-name>-flaskpipelines. La dirección URL de la aplicación se convierte en <your-appservice.azurewebsites.net>.

    az webapp up --name <your-web-app-name>
    

    La salida JSON del comando az webapp up muestra:

    {
      "URL": <your-web-app-url>,
      "appserviceplan": <your-app-service-plan-name>,
      "location": <your-azure-location>,
      "name": <your-web-app-name>,
      "os": "Linux",
      "resourcegroup": <your-resource-group>,
      "runtime_version": "python|3.11",
      "runtime_version_detected": "-",
      "sku": <sku>,
      "src_path": <repository-source-path>
    }
    

    Anote los valores URL y runtime_version. Use runtime_version en el archivo YAML de la canalización. La URL es la dirección URL de la aplicación web. Puede usarla para comprobar que la aplicación se está ejecutando.

    Nota:

    El comando az webapp up realiza las acciones siguientes:

    • Cree un grupo de recursos predeterminado.

    • Cree un plan de App Service predeterminado.

    • Cree una aplicación con el nombre especificado.

    • Implemente desde un archivo ZIP todos los archivos del directorio de trabajo actual, con la automatización de creación habilitada.

    • Almacene los parámetros localmente en el archivo .azure/config para que no tenga que especificarlos de nuevo al implementar posteriormente con az webapp up u otros comandos az webapp desde la carpeta del proyecto. Los valores almacenados en caché se usan automáticamente de forma predeterminada.

    Puede sustituir la acción predeterminada por sus propios valores mediante los parámetros de comando. Para más información, consulte az webapp up.

  4. La aplicación python-sample-vscode-flask-tutorial tiene un archivo startup.txt que contiene el comando de inicio específico de la aplicación web. Establezca la propiedad de configuración startup-file de la aplicación web en startup.txt.

    1. En la salida del comando az webapp up, copie el valor de resourcegroup.

    2. Escriba el siguiente comando, con el grupo de recursos y el nombre de la aplicación.

    az webapp config set --resource-group <your-resource-group> --name <your-web-app-name> --startup-file startup.txt
    

    Cuando el comando finaliza, muestra la salida JSON que contiene todas las opciones de configuración de la aplicación web.

  5. Para ver la aplicación en ejecución, abra un explorador y vaya a la URL que se muestra en la salida del comando az webapp up. Si ve una página genérica, espere unos segundos a que se inicie App Service y, a continuación, actualice la página. Compruebe que ve el título Visual Studio Flask Tutorial.

Crear un proyecto de Azure DevOps.

Cree un proyecto de Azure DevOps nuevo.

  1. En un explorador, vaya a dev.azure.com e inicie sesión.
  2. Seleccione su organización.
  3. Para crear un nuevo proyecto, seleccione Nuevo proyecto o Crear proyecto si va a crear el primer proyecto de la organización.
  4. Escriba un nombre de proyecto.
  5. Seleccione la visibilidad del proyecto.
  6. Seleccione Crear.
  1. En un explorador, vaya a Azure DevOps Server.
  2. Seleccione la colección.
  3. Para crear un nuevo proyecto, seleccione Nuevo proyecto o Crear proyecto si va a crear el primer proyecto de la colección.
  4. Escriba un nombre de proyecto.
  5. Seleccione la visibilidad del proyecto.
  6. Seleccione Crear.

Creación de una entidad de servicio

Una entidad de servicio es una identidad creada para su uso con aplicaciones, servicios hospedados y herramientas automatizadas para acceder a los recursos de Azure. Este acceso está restringido a los roles asignados a la entidad de servicio, lo que permite controlar a qué recursos pueden tener acceso y en qué nivel.

Para crear una entidad de servicio, vaya a Cloud Shell (Bash) y ejecute el siguiente comando. Sustituya <service-principal-name> por un nombre para la entidad de servicio, <your-subscription-id> por el identificador de suscripción y <your-resource-group> por el grupo de recursos de la aplicación web.

az ad sp create-for-rbac --display-name <service-principal-name> --role contributor --scopes /subscriptions/<your-subscription-id>/resourceGroups/<your-resource-group>

El comando devuelve un objeto JSON similar al ejemplo siguiente:

{
  "clientId": "<client GUID>",
  "clientSecret": "<string-value>",
  "subscriptionId": "<subscription GUID>",
  "tenantId": "<tenant GUID>",
  ...
}

Anote los valores clientId, clientSecret, subscriptionId y tenantId. Necesita estos valores para crear una conexión de servicio en la sección siguiente.

Creación de una conexión de servicio

Una conexión de servicio permite crear una conexión para proporcionar acceso autenticado desde Azure Pipelines a servicios externos y remotos. Para implementar en la aplicación web de App de Azure Service, cree una conexión de servicio al grupo de recursos que contiene la aplicación web.

  1. En la página del proyecto, seleccione Configuración del proyecto.

    Captura de pantalla del botón de configuración del proyecto en el panel del proyecto.

  2. Seleccione Conexiones de servicio en la sección Canalizaciones del menú.

  3. Seleccione Crear conexión del servicio.

  4. Seleccione Azure Resource Manager y, a continuación, seleccione Siguiente.

    Captura de pantalla de la selección de la conexión de servicio de Azure Resource Manager.

  5. Seleccione el método de autenticación y seleccione Siguiente.

  6. En el cuadro de diálogo Nueva conexión del servicio de Azure, escriba la información específica del método de autenticación seleccionado. Para obtener más información sobre los métodos de autenticación, consulte Conexión con Azure mediante una conexión de servicio de Azure Resource Manager.

    Por ejemplo, si usa un método de autenticación de Federación de identidades de carga de trabajo (automática) o Entidad de servicio (automática), escriba la información necesaria.

    Captura de pantalla del cuadro de diálogo Nueva conexión de servicio.

    Campo Descripción
    Nivel de ámbito SeleccioneSuscripción.
    Suscripción El nombre de la suscripción de Azure.
    Grupo de recursos Nombre del grupo de recursos que contiene la aplicación web.
    Nombre de conexión de servicio Un nombre descriptivo para la conexión.
    Conceder permisos de acceso a todas las canalizaciones Seleccione esta opción para conceder acceso a todas las canalizaciones.
  7. Seleccione Guardar.

La nueva conexión aparece en la lista Conexiones de servicio y está lista para su uso en Azure Pipeline.

  1. En la página del proyecto, seleccione Configuración del proyecto.

    Captura de pantalla del botón de configuración del proyecto en el panel del proyecto.

  2. Seleccione Conexiones de servicio en la sección Canalizaciones del menú.

  3. Seleccione Crear conexión del servicio.

  4. Seleccione Azure Resource Manager y, a continuación, seleccione Siguiente.

    Captura de pantalla de la selección de la conexión de servicio de Azure Resource Manager.

  5. En Nueva conexión de servicio de Azure, seleccione Entidad de servicio (manual) y Siguiente.

  6. En el cuadro de diálogo siguiente, rellene la información necesaria.

    Captura de pantalla del cuadro de diálogo Nueva conexión de servicio.

    Campo Descripción
    Entorno Seleccione Azure Cloud.
    Nivel de ámbito SeleccioneSuscripción.
    Id. de suscripción El identificador de suscripción.
    Subscription Name El nombre de la suscripción de Azure.
    Id. de entidad de servicio El valor appId del objeto JSON devuelto por el comando az ad sp create-for-rbac.
    Clave de entidad de servicio El valor password del objeto JSON devuelto por el comando az ad sp create-for-rbac.
    Identificador de inquilino El valor tenant del objeto JSON devuelto por el comando az ad sp create-for-rbac.
  7. Seleccione Verificar para verificar la conexión.

  8. Escriba un Nombre de conexión de servicio.

  9. Asegúrese de que está seleccionada la opción Conceder permisos de acceso a todas las canalizaciones.

  10. Seleccione Comprobar y guardar.

La nueva conexión aparece en la lista Conexiones de servicio y está lista para que Azure Pipelines la use desde el proyecto.

Configuración de un agente autohospedado

Si usa su propio agente autohospedado, debe configurarlo para ejecutar Python. No se admite la descarga de versiones de Python en agentes autohospedados. Debe preinstalar la versión de Python. Use el instalador completo para obtener una versión compatible con pip de Python.

Para evitar problemas de incompatibilidad, debe hacer coincidir la versión de Python con la versión en tiempo de ejecución en su aplicación web de Azure App Services. La versión en tiempo de ejecución se muestra en la salida JSON del comando az webapp up.

La versión de Python deseada debe agregarse a la memoria caché de herramientas en el agente autohospedado para que la tarea pueda usarla. Normalmente, la caché de la herramienta se encuentra en el directorio _work/_tool del agente; como alternativa, la ruta de acceso se puede sustituir por la variable de entorno AGENT_TOOLSDIRECTORY. En el directorio de herramientas, cree la siguiente estructura de directorios basada en su versión de Python:

$AGENT_TOOLSDIRECTORY/
    Python/
        {version number}/
            {platform}/
                {tool files}
            {platform}.complete

El número de versión debe seguir el formato 1.2.3. La plataforma debe ser x86 o x64. Los archivos de la herramienta deben ser los archivos de versión de Python descomprimidos. El {platform}.complete debe ser un archivo de 0 bytes que se parezca a x86.complete o x64.complete y solo significa que la herramienta está instalada correctamente en la caché.

Por ejemplo, si usa Python 3.11 en una máquina Windows de 64 bits, la estructura de directorios tendría el siguiente aspecto:

$AGENT_TOOLSDIRECTORY/
    Python/
        3.11.4/
            x64/
                {python files}
            x64.complete

Si ya tiene la versión de Python que desea usar en la máquina que hospeda el agente, puede copiar los archivos en la memoria caché de herramientas. Si no tiene la versión de Python, puede descargarla desde el sitio web de Python.

Crear una canalización

Cree una canalización para crear e implementar su aplicación web de Python en Azure App Service. Para comprender los conceptos de canalización, vea:

  1. En el menú de navegación izquierdo, seleccione Canalizaciones.

    Captura de pantalla de la selección de Canalizaciones en el panel del proyecto.

  2. Seleccione Crear canalización.

    Captura de pantalla del botón nueva canalización en la lista de canalizaciones.

  3. En el cuadro de diálogo Dónde está el código, seleccione GitHub. Es posible que se le pida que inicie sesión en GitHub.

    Captura de pantalla de la selección de GitHub como ubicación de su código.

  4. En la pantalla Seleccionar un repositorio, seleccione el repositorio de ejemplo bifurcado.

    Captura de pantalla de la selección del repositorio.

  5. Es posible que se le pida que vuelva a escribir la contraseña de GitHub como confirmación.

  6. Si la extensión de Azure Pipelines no está instalada en GitHub, GitHub le pedirá que instale la extensión de Azure Pipelines.

    Instale la extensión de Azure Pipelines en GitHub.

    En esta página, desplácese hacia abajo hasta la sección Acceso al repositorio, elija si desea instalar la extensión en todos los repositorios o solo en los seleccionados y, a continuación, seleccione Aprobar e instalar.

    Captura de pantalla de Aprobar e instalar la extensión de Azure Pipelines en GitHub.

  7. En el cuadro de diálogo Configuración de la canalización, seleccione Aplicación web de Python a Linux en Azure.

  8. Seleccione la suscripción de Azure y seleccione Continuar.

  9. Si usa su nombre de usuario y la contraseña para autenticarse, se abre un explorador para que inicie sesión en su cuenta Microsoft.

  10. Seleccione el nombre de la aplicación web en la lista desplegable y seleccione Validar y configurar.

Azure Pipelines crea un archivo azure-pipelines.yml y lo muestra en el editor de canalizaciones de YAML. El archivo de canalización define la canalización de CI/CD como una serie de fases, trabajos y pasos, donde cada paso contiene los detalles de diferentes tareas y scripts. Eche un vistazo a la canalización para ver lo que hace. Asegúrese de que todas las entradas predeterminadas sean adecuadas para el código.

  1. En el menú de navegación, seleccione Canalizaciones.

    Captura de pantalla de la selección de Canalizaciones en el panel del proyecto.

  2. Seleccione Crear canalización.

    Captura de pantalla del botón Nueva canalización.

  3. En el cuadro de diálogo Dónde está el código, seleccione GitHub Enterprise Server. Es posible que se le pida que inicie sesión en GitHub.

    Captura de pantalla de la selección de GitHub como ubicación de su código.

  4. En la pestaña Seleccionar un repositorio, seleccione el repositorio de ejemplo bifurcado.

    Captura de pantalla de la selección del repositorio.

  5. Es posible que se le pida que vuelva a escribir la contraseña de GitHub como confirmación.

  6. Si la extensión de Azure Pipelines no está instalada en GitHub, GitHub le pedirá que instale la extensión de Azure Pipelines.

    Captura de pantalla de la extensión de Azure Pipelines en GitHub.

    En esta página, desplácese hacia abajo hasta la sección Acceso al repositorio, elija si desea instalar la extensión en todos los repositorios o solo en los seleccionados y, a continuación, seleccione Aprobar e instalar.

    Captura de pantalla de Aprobar e instalar la extensión de Azure Pipelines en GitHub.

  7. En el cuadro de diálogo Configurar su canalización, seleccione Canalización inicial.

  8. Reemplace el contenido del archivo azure-pipelines.yml por el código siguiente.

    trigger:
    - main
    
    variables:
      # Azure Resource Manager connection created during pipeline creation
      azureServiceConnectionId: '<your-service-connection-name>'
    
      # Web app name
      webAppName: '<your-web-app-name>'
    
      # Environment name
      environmentName: '<your-web-app-name>'
    
      # Project root folder. 
      projectRoot: $(System.DefaultWorkingDirectory)
    
      # Python version: 
      pythonVersion: '<your-python-version>'
    
    stages:
    - stage: Build
      displayName: Build stage
      jobs:
      - job: BuildJob
        pool:
          name: '<your-pool-name>'
          demands: python
        steps:
        - task: UsePythonVersion@0
          inputs:
            versionSpec: '$(pythonVersion)'
          displayName: 'Use Python $(pythonVersion)'
    
        - script: |
            python -m venv antenv
            source antenv/bin/activate
            python -m pip install --upgrade pip
            pip install -r requirements.txt
          workingDirectory: $(projectRoot)
          displayName: "Install requirements"
    
        - task: ArchiveFiles@2
          displayName: 'Archive files'
          inputs:
            rootFolderOrFile: '$(projectRoot)'
            includeRootFolder: false
            archiveType: zip
            archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
            replaceExistingArchive: true
    
        - task: PublishBuildArtifacts@1
          inputs:
            PathtoPublish: '$(Build.ArtifactStagingDirectory)'
            ArtifactName: 'drop'
            publishLocation: 'Container'
    
    - stage: Deploy
      displayName: 'Deploy Web App'
      dependsOn: Build
      condition: succeeded()
      jobs:
      - deployment: DeploymentJob
        pool:
          name: '<your-pool-name'
        environment: $(environmentName)
        strategy:
          runOnce:
            deploy:
              steps:
    
              - task: UsePythonVersion@0
                inputs:
                  versionSpec: '$(pythonVersion)'
                displayName: 'Use Python version'
    
              - task: AzureWebApp@1
                displayName: 'Deploy Azure Web App : <your-web-app-name>'
                inputs:
                  azureSubscription: $(azureServiceConnectionId)
                  appName: $(webAppName)
                  package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
                  startUpCommand: 'startup.txt'
    
    
  9. Reemplace los siguientes marcadores de posición por sus propios valores:

    Marcador de posición Descripción
    <your-service-connection-name> Nombre de la conexión de servicio que creó.
    <your-web-app-name> Nombre de su aplicación web de Azure App Service.
    <your-pool-name> Nombre del grupo de agentes que quiere usar.
    <your-python-version> Versión de Python que se ejecuta en el agente. Es recomendable que haga coincidir esta versión con la versión de Python que se ejecuta en la aplicación web. La versión de la aplicación web se muestra en la salida JSON del comando az webapp up.

Archivo de canalización YAML

En la explicación siguiente se describe el archivo de canalización YAML. Para obtener información sobre el esquema del archivo YAML de canalización, consulte Referencia de esquema de YAML.

A continuación se muestra el archivo YAML de ejemplo completo:

trigger:
- main

variables:
  # Azure Resource Manager connection created during pipeline creation
  azureServiceConnectionId: '<GUID>'

  # Web app name
  webAppName: '<your-webapp-name>'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

  # Environment name
  environmentName: '<your-webapp-name>'

  # Project root folder. Point to the folder containing manage.py file.
  projectRoot: $(System.DefaultWorkingDirectory)

  pythonVersion: '3.11'

stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: BuildJob
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: UsePythonVersion@0
      inputs:
        versionSpec: '$(pythonVersion)'
      displayName: 'Use Python $(pythonVersion)'

    - script: |
        python -m venv antenv
        source antenv/bin/activate
        python -m pip install --upgrade pip
        pip install setup
        pip install -r requirements.txt
      workingDirectory: $(projectRoot)
      displayName: "Install requirements"

    - task: ArchiveFiles@2
      displayName: 'Archive files'
      inputs:
        rootFolderOrFile: '$(projectRoot)'
        includeRootFolder: false
        archiveType: zip
        archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
        replaceExistingArchive: true

    - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
      displayName: 'Upload package'
      artifact: drop

- stage: Deploy
  displayName: 'Deploy Web App'
  dependsOn: Build
  condition: succeeded()
  jobs:
  - deployment: DeploymentJob
    pool:
      vmImage: $(vmImageName)
    environment: $(environmentName)
    strategy:
      runOnce:
        deploy:
          steps:

          - task: UsePythonVersion@0
            inputs:
              versionSpec: '$(pythonVersion)'
            displayName: 'Use Python version'

          - task: AzureWebApp@1
            displayName: 'Deploy Azure Web App : $(webAppName)'
            inputs:
              azureSubscription: $(azureServiceConnectionId)
              appName: $(webAppName)
              package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip

Variables

La sección variables contiene las siguientes variables:

variables:
# Azure Resource Manager connection created during pipeline creation
azureServiceConnectionId: '<GUID>'

# Web app name
webAppName: '<your-webapp-name>'

# Agent VM image name
vmImageName: 'ubuntu-latest'

# Environment name
environmentName: '<your-webapp-name>'

# Project root folder.
projectRoot: $(System.DefaultWorkingDirectory)

# Python version: 3.11. Change this to match the Python runtime version running on your web app.
pythonVersion: '3.11'

Variable Descripción
azureServiceConnectionId El identificador o nombre de la conexión de servicio de Azure Resource Manager.
webAppName Nombre de la aplicación web de Azure App Service.
vmImageName Nombre del sistema operativo que se va a usar para el agente de creación.
environmentName Nombre del entorno usado en la fase de implementación. El entorno se crea automáticamente cuando se ejecuta el trabajo de fase.
projectRoot Carpeta raíz que contiene el código de la aplicación.
pythonVersion Versión de Python que se va a usar en los agentes de compilación e implementación.

La sección variables contiene las siguientes variables:

variables:
# Azure Resource Manager connection created during pipeline creation
azureServiceConnectionId: '<your-service-connection-name>'

# Web app name
webAppName: '<your-webapp-name>'

# Environment name
environmentName: '<your-webapp-name>'

# Project root folder. 
projectRoot: $(System.DefaultWorkingDirectory)

# Python version: 3.11. Change this to the version that is running on your agent and web app.
pythonVersion: '3.11'
Variable Descripción
azureServiceConnectionId Nombre de la conexión de servicio de Azure Resource Manager.
webAppName el nombre de la aplicación web.
environmentName Nombre del entorno usado en la fase de implementación.
projectRoot Carpeta que contiene el código de la aplicación. El valor es una variable del sistema automática.
pythonVersion Versión de Python que se va a usar en los agentes de compilación e implementación.

Fase de compilación

La fase de compilación contiene un único trabajo que se ejecuta en el sistema operativo definido en la variable vmImageName.

  - job: BuildJob
    pool:
      vmImage: $(vmImageName)

La fase de compilación contiene un único trabajo que se ejecuta en un agente del grupo identificado por el parámetro name. Puede especificar las funcionalidades del agente con la palabra clave demands. Por ejemplo, demands: python especifica que el agente debe tener instalado Python. Para especificar un agente autohospedado por nombre, puede usar la palabra clave demands: Agent.Name -equals <agent-name>.

  - job: BuildJob
    pool:
      name: <your-pool-name>
      demands: python

El trabajo contiene varios pasos:

  1. La tarea UsePythonVersion selecciona la versión de Python que se va a usar. La versión se define en la variable pythonVersion.

       - task: UsePythonVersion@0
          inputs:
            versionSpec: '$(pythonVersion)'
            displayName: 'Use Python $(pythonVersion)'
    
  2. En este paso se usa un script para crear un entorno de Python virtual e instalar las dependencias de la aplicación contenidas en el requirements.txt parámetro The workingDirectory especifica la ubicación del código de la aplicación.

      - script: |
           python -m venv antenv
           source antenv/bin/activate
           python -m pip install --upgrade pip
           pip install setup
           pip install  -r ./requirements.txt
         workingDirectory: $(projectRoot)
         displayName: "Install requirements"
    
  3. La tarea ArchiveFiles crea el archivo .zip archivo que contiene la aplicación web. El archivo .zip se carga en la canalización como el artefacto denominado drop. El archivo .zip se usa en la fase de implementación para implementar la aplicación en la aplicación web.

       - task: ArchiveFiles@2
         displayName: 'Archive files'
         inputs:
           rootFolderOrFile: '$(projectRoot)'
           includeRootFolder: false
           archiveType: zip
           archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
           replaceExistingArchive: true
    
       - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
         displayName: 'Upload package'
         artifact: drop
    
    Parámetro Descripción
    rootFolderOrFile Ubicación del código de la aplicación.
    includeRootFolder Indica si se debe incluir la carpeta raíz en el archivo .zip. Establezca este parámetro en false; de lo contrario, el contenido del archivo .zip se coloca en una carpeta denominada s y App Service en el contenedor de Linux no encuentra el código de la aplicación.
    archiveType El tipo de archivo que se va a crear. Establécelo en zip.
    archiveFile Ubicación del archivo .zip que se va a crear.
    replaceExistingArchive Indica si se va a reemplazar un archivo existente si el archivo ya existe. Establécelo en true.
    upload Ubicación del archivo .zip que se va a cargar.
    artifact Nombre del artefacto que se va a crear.

Fase de implementación

La fase de implementación se ejecuta si la fase de compilación se completa correctamente. Las siguientes palabras clave definen este comportamiento:

  dependsOn: Build
  condition: succeeded()

La fase de implementación contiene un único trabajo de implementación configurado con las siguientes palabras clave:

  - deployment: DeploymentJob
    pool:
      vmImage: $(vmImageName)
    environment: $(environmentName)
Palabra clave Descripción
deployment Indica que el trabajo es un trabajo de implementación que tiene como destino un entorno.
pool Especifica el grupo de agentes de implementación. Grupo de agentes predeterminado si no se especifica el nombre. La palabra clave vmImage identifica el sistema operativo de la imagen de máquina virtual del agente.
environment Especifica el entorno en el que se va a implementar. El entorno se crea automáticamente en el proyecto cuando se ejecuta el trabajo.
  - deployment: DeploymentJob
    pool:
      name: <your-pool-name>
    environment: $(environmentName)
Palabra clave Descripción
deployment Indica que el trabajo es un trabajo de implementación que tiene como destino un entorno.
pool Especifica el grupo de agentes que se va a usar para la implementación. Este grupo debe contener un agente con la capacidad de ejecutar la versión de Python especificada en la canalización.
environment Especifica el entorno en el que se va a implementar. El entorno se crea automáticamente en el proyecto cuando se ejecuta el trabajo.

La palabra clave strategy se usa para definir la estrategia de implementación. La palabra clave runOnce especifica que el trabajo de implementación se ejecuta una vez. La palabra clave deploy especifica los pasos que se van a ejecutar en el trabajo de implementación.

  strategy:
    runOnce:
      deploy:
        steps:

Los steps de la canalización son los siguientes:

  1. Use la tarea UsePythonVersion para especificar la versión de Python que se va a usar en el agente. La versión se define en la variable pythonVersion.

     - task: UsePythonVersion@0
       inputs:
         versionSpec: '$(pythonVersion)'
       displayName: 'Use Python version'
    
  2. Implemente la aplicación web mediante AzureWebApp@1. Esta tarea implementa el artefacto de canalización drop en la aplicación web.

    - task: AzureWebApp@1
       displayName: 'Deploy Azure Web App : <your-web-app-name>'
       inputs:
          azureSubscription: $(azureServiceConnectionId)
          appName: $(webAppName)
          package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
    
    Parámetro Descripción
    azureSubscription El identificador o nombre de la conexión de servicio de Azure Resource Manager que se va a utilizar.
    appName el nombre de la aplicación web.
    package Ubicación del archivo .zip que se va a implementar.

    Además, debido a que el repositorio python-vscode-flask-tutorial contiene el mismo comando de inicio en un archivo llamado startup.txt, puede especificar ese archivo agregando el parámetro: startUpCommand: 'startup.txt'.

Los steps de la canalización son los siguientes:

  1. Use la tarea UsePythonVersion para especificar la versión de Python que se va a usar en el agente. La versión se define en la variable pythonVersion.

     - task: UsePythonVersion@0
       inputs:
         versionSpec: '$(pythonVersion)'
       displayName: 'Use Python version'
    
  2. Implemente la aplicación web mediante AzureWebApp@1. Esta tarea implementa el artefacto de canalización drop en la aplicación web.

    - task: AzureWebApp@1
       displayName: 'Deploy Azure Web App : <your-web-app-name>'
       inputs:
          azureSubscription: $(azureServiceConnectionId)
          appName: $(webAppName)
          package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
    
    Parámetro Descripción
    azureSubscription El identificador o nombre de la conexión de servicio de Azure Resource Manager que se va a utilizar.
    appName el nombre de la aplicación web.
    package Ubicación del archivo .zip que se va a implementar.

    Además, debido a que el repositorio python-vscode-flask-tutorial contiene el mismo comando de inicio en un archivo llamado startup.txt, puede especificar ese archivo agregando el parámetro: startUpCommand: 'startup.txt'.

      - task: AzureWebApp@1
         displayName: 'Deploy Azure Web App : $(webAppName)'
         inputs:
           azureSubscription: $(azureServiceConnectionId)
           appName: $(webAppName)
           package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
           startUpCommand: 'startup.txt'
    
    Parámetro Descripción
    azureSubscription El identificador o nombre de la conexión de servicio de Azure Resource Manager que se va a utilizar.
    appName el nombre de la aplicación web.
    package Ubicación del archivo .zip que se va a implementar.
    startUpCommand Comando que se va a ejecutar después de implementar la aplicación. La aplicación de ejemplo usa startup.txt.

Ejecución de la canalización

Ya está todo listo para probarlo.

  1. En el editor, seleccione Guardar y ejecutar.

  2. En el cuadro de diálogo Guardar y ejecutar, agregue un mensaje de confirmación y, a continuación, seleccione Guardar y ejecutar.

    Puede ver la canalización a medida que se ejecuta seleccionando las fases o los trabajos en el resumen de ejecución de la canalización.

    Captura de pantalla de la sección de fases del resumen de ejecución de la canalización.

    Hay marcas de verificación verdes junto a cada fase y trabajo a medida que se completa correctamente. Si se producen errores, se muestran en el resumen o en los pasos del trabajo.

    Captura de pantalla de los pasos de la fase de canalización.

    Para volver rápidamente al editor de YAML, seleccione los puntos verticales en la parte superior derecha de la página Resumen y seleccione Editar canalización:

    Captura de pantalla del comentario de editar canalización de un informe de compilación.

  3. En el trabajo de implementación, seleccione la tarea Implementar aplicación web de Azure para mostrar su salida. Para visitar el sitio implementado, mantenga presionada la tecla Ctrl y seleccione la dirección URL tras App Service Application URL.

    Si usa la aplicación de ejemplo, la aplicación debería aparecer de la siguiente manera:

    Captura de pantalla de la vista de la aplicación de ejemplo que se ejecuta en App Service.

Importante

Si se produce un error en la aplicación debido a una dependencia que falta, significa que el archivo requirements.txt no se procesó durante la implementación. Este comportamiento se produce si creó la aplicación web directamente en el portal en lugar de usar el comando az webapp up como se muestra en este artículo.

El comando az webapp up establece específicamente la acción de compilación SCM_DO_BUILD_DURING_DEPLOYMENT en true. Si aprovisionó el servicio de aplicaciones a través del portal, esta acción no se establece automáticamente.

Los pasos siguientes establecen la acción:

  1. Abra Azure Portal, seleccione la instancia de App Service y, a continuación, elija Configuración.
  2. En la pestaña Configuración de aplicaciones, seleccione Nueva configuración de aplicación.
  3. En el menú emergente que aparece, establezca Nombre en SCM_DO_BUILD_DURING_DEPLOYMENT, establezca Valor en true y seleccione Aceptar.
  4. Seleccione Guardar en la parte superior de la página Configuración.
  5. Repetición de la ejecución de la canalización Las dependencias deben instalarse durante la implementación.

Desencadenamiento de una ejecución de la canalización

Para desencadenar una ejecución de canalización, confirme un cambio en el repositorio. Por ejemplo, puede agregar una nueva característica a la aplicación o actualizar las dependencias de la aplicación.

  1. Vaya al repositorio de GitHub.
  2. Realice un cambio en el código, como cambiar el título de la aplicación.
  3. Confirme el cambio en el repositorio.
  4. Vaya a la canalización y compruebe que se ha creado una nueva ejecución.
  5. Cuando finalice la ejecución, compruebe que la nueva creación se ha implementado en la aplicación web.
    1. En Azure Portal, vaya a la aplicación web.
    2. Seleccione Centro de implementación y seleccione la pestaña Registros.
    3. Compruebe que aparece la nueva implementación.

Consideraciones para Django

Puede usar Azure Pipelines para implementar aplicaciones de Django en Azure App Service en Linux si usa una base de datos independiente. No se puede usar una base de datos SQLite, ya que App Service bloquea el archivo db.sqlite3, lo que impide tanto las lecturas como las escrituras. Este comportamiento no afecta a una base de datos externa.

Como se describe en Configuración de la aplicación de Python en App Service: proceso de inicio del contenedor, App Service busca automáticamente un archivo wsgi.py en el código de la aplicación, que normalmente contiene el objeto de aplicación. Si desea personalizar el comando de inicio de cualquier manera, use el parámetro startUpCommand en el paso AzureWebApp@1 del archivo de canalización de YAML, como se describe en la sección anterior.

Al usar Django, normalmente quiere migrar los modelos de datos mediante manage.py migrate después de implementar el código de la aplicación. Puede agregar startUpCommand con un script posterior a la implementación para este propósito. Por ejemplo, esta es la propiedad startUpCommand de la tarea AzureWebApp@1.

  - task: AzureWebApp@1
      displayName: 'Deploy Azure Web App : $(webAppName)'
      inputs:
        azureSubscription: $(azureServiceConnectionId)
        appName: $(webAppName)
        package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
        startUpCommand: 'python manage.py migrate'

Ejecución de pruebas en el agente de compilación

Como parte del proceso de compilación, puede que desee ejecutar pruebas en el código de la aplicación. Las pruebas se ejecutan en el agente de compilación, por lo que debe instalar las dependencias en un entorno virtual en el agente de compilación. Una vez ejecutadas las pruebas, elimine el entorno virtual antes de crear el archivo .zip para la implementación. Los siguientes elementos de script muestran este proceso. Colóquelos antes de la tarea ArchiveFiles@2 en el archivo azure-pipelines.yml. Para más información, consulte Ejecución de scripts multiplataforma.

# The | symbol is a continuation character, indicating a multi-line script.
# A single-line script can immediately follow "- script:".
- script: |
    python -m venv .env
    source .env/bin/activate
    pip install setuptools
    pip install -r requirements.txt

  # The displayName shows in the pipeline UI when a build runs
  displayName: 'Install dependencies on build agent'

- script: |
    # Put commands to run tests here
    displayName: 'Run tests'

- script: |
    echo Deleting .env
    deactivate
    rm -rf .env
  displayName: 'Remove .env before zip'

También puede usar una tarea como PublishTestResults@2 para publicar los resultados de las pruebas en la canalización. Para más información, consulte Compilación de aplicaciones de Python: ejecución de pruebas.

Limpieza de recursos

Para evitar incurrir en cargos en los recursos de Azure creados en este tutorial:

  • Elimine el proyecto que creó. Al eliminar el proyecto, se elimina la canalización y la conexión de servicio.

  • Elimine el grupo de recursos de Azure que contiene App Service y el plan de App Service. En Azure Portal, vaya al grupo de recursos, seleccione Eliminar grupo de recursos y siga las indicaciones.

  • Elimine la cuenta de almacenamiento que mantiene el sistema de archivos para Cloud Shell. Cierre Cloud Shell y, a continuación, vaya al grupo de recursos que comienza con cloud-shell-storage-, seleccione Eliminar grupo de recursos y siga las indicaciones.

Pasos siguientes