Usare Azure Pipelines per compilare e distribuire un'app Web Python nel servizio app Azure

Servizi di Azure DevOps

Questa esercitazione illustra come usare Azure Pipelines per l'integrazione continua e il recapito continuo (CI/CD) per compilare e distribuire un'app Web Python nel servizio app di Azure in Linux. La pipeline compila e distribuisce automaticamente l'app web Python in App Service ogni volta che viene effettuato un commit nel repository del codice sorgente dell'app.

In questa esercitazione, farai:

  • Creare un'app Web Python e caricarla nel servizio app di Azure.
  • Connettere il progetto Azure DevOps ad Azure.
  • Crea una pipeline di compilazione e distribuzione specifica per Python in Azure Pipelines per la tua app.
  • Esegui la pipeline per compilare, eseguire i test e distribuire nell'app Web del tuo servizio app di Azure.
  • Imposta un trigger per eseguire la pipeline ogni volta che effettui un commit al tuo repository.

Per altre informazioni sui concetti di Azure Pipelines, guardare il video seguente:

Prerequisiti

Prodotto Requisiti
Azure DevOps - Un progetto Azure DevOps.
- Possibilità di eseguire pipeline su agenti ospitati da Microsoft. Abilitare il livello gratuito o acquistare un processo parallelo.
- Conoscenza di base di YAML e Azure Pipelines. Per maggiori informazioni, vedere Creare la prima pipeline.
Autorizzazioni - :
     - Per creare una pipeline, è necessario trovarsi nel gruppo Collaboratori e il gruppo deve avere l'autorizzazione Crea pipeline di compilazione impostata su Consenti. I membri del gruppo Project Administrators possono gestire le pipeline.
    - Per creare connessioni al servizio: è necessario disporre del ruolo di Administrator o Creator per le connessioni al servizio .
GitHub - Un account GitHub.
- Una connessione al servizio GitHub per autorizzare Azure Pipelines.
Azzurro Una sottoscrizione di Azure.
Prodotto Requisiti
Azure DevOps - Un progetto Azure DevOps.
- Agente ospitato autonomamente. Per crearne uno, vedere la sezione su Agenti self-hosted.
- Conoscenza di base di YAML e Azure Pipelines. Per maggiori informazioni, vedere Creare la prima pipeline.
Autorizzazioni - :
    - Per creare una pipeline, è necessario trovarsi nel gruppo Collaboratori e il gruppo deve avere l'autorizzazione Crea pipeline di compilazione impostata su Consenti. I membri del gruppo Project Administrators possono gestire le pipeline.
    - Per creare connessioni al servizio: è necessario disporre del ruolo di Administrator o Creator per le connessioni al servizio .
GitHub - Un account GitHub.
- Una connessione al servizio GitHub per autorizzare Azure Pipelines.
Azzurro Una sottoscrizione di Azure.

Configurare un agente ospitato autonomamente

Il download delle versioni di Python non è supportato in agenti di compilazione self-hosted. Per usare il tuo agente ospitato autonomamente, devi configurarlo affinché esegua Python.

Per evitare problemi di compatibilità, fai in modo che la versione di Python corrisponda alla versione di runtime nell'app Web di app Azure Services, 3.11 in questo caso. È necessario preinstallare la versione di Python. Usare il programma di installazione completo per ottenere una versione compatibile con pip di Python.

La versione di Python desiderata deve essere aggiunta alla cache degli strumenti nell'agente self-hosted in modo che l'attività della pipeline possa usarla. In genere, la cache degli strumenti si trova nella directory _work/_tool dell'agente. In alternativa, è possibile eseguire l'override del percorso con la variabile AGENT_TOOLSDIRECTORYdi ambiente . Nella directory degli strumenti creare la struttura di directory seguente in base alla versione di Python:

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

Il numero di versione deve seguire il formato 1.2.3. La piattaforma deve essere x86 o x64. I file degli strumenti devono essere i file di versione di Python decompressi. Deve {platform}.complete essere un file a 0 byte simile x86.complete o x64.complete e indica semplicemente che lo strumento è installato correttamente nella cache.

Ad esempio, per usare Python 3.11 in un computer Windows a 64 bit, creare la struttura di directory seguente:

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

Se il computer che ospita l'agente ha già la versione python che si vuole usare, è possibile copiare i file nella cache degli strumenti. Se non si ha la versione di Python, è possibile scaricarla dal sito Web Python.

Preparare l'app di esempio

  1. Fai il fork del repository di esempio nel tuo account GitHub https://github.com/Microsoft/python-sample-vscode-flask-tutorial.

  2. Clona il fork sul computer locale usando git clone <your-forked-repository-url>.git.

  3. Passare al clone locale usando cd python-sample-vscode-flask-tutoriale compilare ed eseguire l'app in locale per assicurarsi che funzioni.

    python -m venv .env
    source .env/Scripts/activate
    pip install --upgrade pip
    pip install -r ./requirements.txt
    export FLASK_APP=hello_app.webapp
    flask run
    
  4. Per testare l'app, passare a http://localhost:5000 in una finestra del browser e verificare che venga visualizzato il titolo Visual Studio Flask Tutorial.

  5. Chiudere la finestra del browser e arrestare il server Flask usando CTRL+C.

Creare e distribuire l'app Web di App Service

Creare l'app Web del servizio app di Azure usando Cloud Shell nel portale di Azure. Per usare Cloud Shell, accedere al portale di Azure e selezionare il pulsante Cloud Shell sulla barra degli strumenti.

Screenshot del pulsante Azure Cloud Shell sulla barra degli strumenti portale di Azure.

Cloud Shell viene visualizzato nella parte inferiore del browser. Assicurarsi che Bash sia selezionato come ambiente nel menu a discesa. È possibile ingrandire la finestra di Cloud Shell per offrire maggiore spazio.

Screenshot di Azure Cloud Shell.

Suggerimento

Per incollare in Cloud Shell, usa Ctrl+Maiusc+V o fai clic con il pulsante destro e seleziona Incolla dal menu di scelta rapida.

Creare e distribuire l'app Web

  1. In Cloud Shell, clona su Azure il repository di cui hai eseguito il fork con il comando seguente, sostituendo <your-forked-repository-url> con l'URL del repository di cui hai eseguito il fork.

    git clone <your-forked-repository-url>
    
  2. Passa alla cartella del repository clonato.

    cd python-sample-vscode-flask-tutorial
    
  3. Esegui il comando az webapp up per eseguire il provisioning dell'app Web di App Service ed effettuare la prima distribuzione. Usare il --name <your-web-app-name> parametro per assegnare un nome univoco in Azure, ad esempio un nome personale o aziendale insieme a un identificatore dell'app, ad --name <your-name>-flaskpipelinesesempio . L'esecuzione az webapp up senza parametri assegna un nome di app Web generato in modo casuale univoco in Azure.

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

Il az webapp up comando riconosce l'app come app Python e esegue le azioni seguenti:

  1. Crea un gruppo di risorse predefinito.
  2. Crea un piano di servizio app predefinito.
  3. Crea un'app Web con il nome assegnato. L'app URL è <your-web-app-name>.azurewebsites.net.
  4. Distribuisce tutti i file dalla directory di lavoro corrente a un archivio ZIP, con l'automazione della compilazione abilitata.
  5. Memorizza nella cache i parametri in locale nel file .azure/config , quindi non è necessario specificarli di nuovo durante la distribuzione dalla cartella del progetto con az webapp up o altri az webapp comandi. I comandi usano automaticamente i valori memorizzati nella cache per impostazione predefinita.

È possibile eseguire l'override delle azioni predefinite con i propri valori usando i parametri del comando. Per altre informazioni, vedere az webapp up.

Il az webapp up comando produce l'output JSON seguente per l'app Web di esempio:

{
  "URL": <your-web-app-url>,
  "appserviceplan": <your-app-service-plan-name>,
  "location": <your-azure-region>,
  "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>
}

Annota i valori URL, resourcegroup e runtime_version da utilizzare più avanti in questa esercitazione.

Impostare il comando di avvio

L'app python-sample-vscode-flask-tutorial include un file startup.txt che contiene il comando di avvio specifico per l'app Web. Impostare la proprietà di configurazione startup-file dell'app Web su startup.txt immettendo il comando seguente e usando i nomi del gruppo di risorse e dell'app Web.

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

Al termine del comando, l'output JSON mostra tutte le impostazioni di configurazione per l'app Web.

Per visualizzare l'app in esecuzione, aprire un browser e passare al URL mostrato nell'output del comando az webapp up. Se viene visualizzata una pagina generica, attendere alcuni secondi per l'avvio del servizio app, quindi aggiornare la pagina. Verifica di vedere il titolo Visual Studio Flask Tutorial.

Connettere il progetto Azure DevOps alla sottoscrizione di Azure

Per usare Azure Pipelines per la distribuzione nell'app Web del servizio app di Azure, è necessario connettere il progetto Azure DevOps alle risorse di Azure.

Creare un principale di servizio

Un'entità servizio è un'identità creata per le applicazioni, i servizi ospitati e gli strumenti automatizzati per accedere alle risorse di Azure. Questo accesso è limitato ai ruoli assegnati all'entità servizio e ti consente di controllare a quali risorse è possibile accedere e a quale livello.

Per creare un'entità servizio, eseguire il comando seguente in Bash Cloud Shell. Sostituire <service-principal-name> con un nome dell'entità servizio, <your-subscription-id> con l'ID della sottoscrizione di Azure e <your-resource-group> con il gruppo di risorse per l'app Web.

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

Il comando restituisce l'oggetto JSON seguente:

{
  "appId": "<client GUID>",
  "displayName": "<service-principal-name">,
  "password": "<password-string>",
  "tenant": "<tenant GUID>"
  ...
}

Prendi nota dei valori appId, password e tenantId da utilizzare per creare una connessione al servizio nella sezione successiva.

Creare una connessione al servizio

Una connessione al servizio fornisce l'accesso autenticato da Azure Pipelines a servizi esterni e remoti. Per distribuire nell'app Web del Servizio app di Azure, creare una connessione di servizio al gruppo di risorse dell'app Web.

  1. Nella pagina del progetto Azure DevOps selezionare Impostazioni progetto.

  2. Da Project Settings, selezionare Pipelines>Service connections.

  3. Nella pagina Connessioni al servizio selezionare Nuova connessione al servizio o Crea connessione al servizio se la connessione al servizio è la prima nel progetto.

    Schermata della selezione delle connessioni del servizio Pipeline in Impostazioni del progetto.

  4. Nella schermata Nuova connessione al servizio selezionare Azure Resource Manager e quindi avanti.

    Screenshot della selezione della connessione al servizio Azure Resource Manager.

  5. Nella schermata Nuova connessione al servizio di Azure selezionare il tipo di identità. In questo esempio viene usata la registrazione dell'app (automatica) consigliata. Per altre informazioni sui metodi di autenticazione, vedere Connettersi ad Azure usando una connessione al servizio Azure Resource Manager.

  6. In Credenziale, seleziona Federazione dell'identità del carico di lavoro (automatica).

  7. Completa i seguenti campi:

    • Livello di ambito: selezionare Sottoscrizione.
    • Sottoscrizione: selezionare una sottoscrizione di Azure.
    • Gruppo di risorse: selezionare il gruppo di risorse che contiene l'app Web.
    • Nome connessione del servizio: immettere un nome descrittivo per la connessione.
    • Concedere le autorizzazioni di accesso a tutte le pipeline: selezionare questa casella di controllo per concedere l'accesso a tutte le pipeline nel progetto.
  8. Seleziona Salva.

    Screenshot della finestra di dialogo Nuova connessione al servizio di Azure.

  1. Nella pagina del progetto Azure DevOps selezionare Impostazioni progetto.

  2. In Impostazioni progetto, selezionare Pipelines>Connessioni di servizio.

  3. Nella pagina Connessioni al servizio selezionare Nuova connessione al servizio o Crea connessione al servizio se la connessione al servizio è la prima nel progetto.

    Screenshot del pulsante delle impostazioni del progetto nel dashboard del progetto.

  4. Nella schermata Nuova connessione al servizio selezionare Azure Resource Manager e quindi avanti.

    Screenshot che mostra la selezione di Azure Resource Manager.

  5. Selezionare Entità servizio (manuale) e quindi selezionare Avanti.

    Screenshot che mostra la selezione di un metodo di autenticazione dell'entità servizio (manuale).

  6. Nella schermata Nuova connessione al servizio di Azure completare i campi seguenti:

    • Ambiente: selezionare Cloud di Azure.
    • Livello di ambito: selezionare Sottoscrizione.
    • ID sottoscrizione: immettere l'ID sottoscrizione di Azure.
    • Nome sottoscrizione: immettere il nome della sottoscrizione di Azure.
  7. Nella sezione Autenticazione completare i campi seguenti:

    • ID dell'entità servizio: Immettere il valore appId restituito dal comando az ad sp create-for-rbac.
    • Credenziale: seleziona Chiave dell'entità servizio.
    • Chiave dell'entità servizio: Immettere il valore restituito dal comando az ad sp create-for-rbac.
    • ID tenant: immettere il tenant valore restituito dal az ad sp create-for-rbac comando.
    • Selezionare Verifica per verificare la connessione.
  8. Nella sezione Dettagli , in Nome connessione del servizio immettere un nome per la connessione al servizio.

  9. Selezionare la casella di controllo Concedi autorizzazioni di accesso a tutte le pipeline.

  10. Selezionare Verifica e salva.

    Screenshot della parte superiore della nuova schermata di connessione al servizio.

La nuova connessione viene visualizzata nell'elenco Connessioni al servizio ed è pronta per l'uso nella pipeline.

Creare un flusso di lavoro

Creare una pipeline per compilare e distribuire l'app Web Python nel servizio app Azure.

  1. Nel menu di spostamento a sinistra per il progetto selezionare Pipeline.

  2. Nella pagina Pipeline selezionare Nuova pipeline o Crea pipeline se la pipeline è la prima nel progetto.

    Screenshot del pulsante della nuova pipeline nell'elenco delle pipeline.

  3. Nella schermata Dove è il codice selezionare GitHub. Potrebbe essere richiesto di accedere a GitHub.

    Schermata della selezione di GitHub come posizione del tuo codice.

  4. Nella schermata Selezionare un repository, selezionare il repository di esempio creato tramite fork. GitHub potrebbe richiedere di immettere nuovamente la password di GitHub o di installare l'app GitHub azure Pipelines . Seguire le istruzioni visualizzate per installare l'app. Per altre informazioni, vedere Autenticazione dell'app GitHub.

    Screenshot della selezione del repository.

  5. Nella pagina Configura la pipeline, selezionare App Web Linux in Azure per Python.

  6. Nella schermata successiva selezionare la sottoscrizione di Azure e selezionare Continua.

  7. Nella schermata successiva selezionare l'app Web di Azure e selezionare Convalida e configura.

Azure Pipelines crea un file azure-pipelines.yml e lo visualizza nell'editor della pipeline YAML.

  1. Nel menu di spostamento a sinistra per il progetto selezionare Pipeline.

  2. Nella pagina Pipeline selezionare Nuova pipeline o Crea pipeline se la pipeline è la prima nel progetto.

    Screenshot del pulsante della nuova pipeline nell'elenco delle pipeline.

  3. Nella pagina Dove si trova il codice, seleziona GitHub Enterprise Server. Potrebbe essere richiesto di accedere a GitHub.

    Screenshot della scelta di GitHub come posizione per il codice.

  4. Nella scheda Selezionare un repository, seleziona il repository di esempio di cui hai creato un fork. GitHub potrebbe richiedere di immettere nuovamente la password di GitHub o installare l'estensione GitHub di Azure Pipelines o l'app. Seguire le istruzioni visualizzate per installare l'app. Per altre informazioni, vedere Accedere ai repository GitHub.

    Screenshot della selezione del repository.

  5. Nella pagina Configura la pipeline selezionare Pipeline di avvio.

  6. Nella pagina Verifica YAML della pipeline sostituire il contenuto del file di azure-pipelines.yml iniziale con il file di pipeline YAML seguente. Nel file YAML:

    • Sostituisci i segnaposto <your-service-connection-name> e <your-web-app-name> con i tuoi valori.

    • Sostituire <your-pool-name> con il nome del pool di agenti che si vuole usare e sostituire <your-python-version> con la versione di Python in esecuzione nell'agente. Questa versione deve corrispondere a runtime_version nell'output JSON del comando az webapp up.

File di pipeline YAML

Nella pagina Esamina il file YAML della pipeline, esamina la pipeline per vedere cosa fa. Assicurarsi che tutti gli input predefiniti siano appropriati per il codice. Per informazioni sullo schema di file YAML della pipeline, vedere le informazioni di riferimento sullo schema YAML.

Il file di pipeline YAML di esempio seguente definisce la pipeline CI/CD come una serie di fasi, processi e passaggi, in cui ogni passaggio contiene i dettagli per attività e script diversi. Il codice YAML generato popola automaticamente i segnaposto con valori per l'app e la connessione.

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 setuptools
        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
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'

Variabili

La variables sezione all'inizio del file YAML definisce le variabili seguenti:

Variabile Descrizione
azureServiceConnectionId ID della connessione al servizio Azure Resource Manager.
webAppName Il nome dell'app Web di App Service.
vmImageName Nome del sistema operativo da usare per l'agente di compilazione.
environmentName Nome dell'ambiente in cui eseguire la distribuzione, che viene creato automaticamente quando viene eseguito il processo di distribuzione.
projectRoot Cartella radice contenente il codice dell'applicazione.
pythonVersion Versione di Python da usare negli agenti di compilazione e distribuzione.
Variabile Descrizione
azureServiceConnectionId ID della connessione al servizio Azure Resource Manager.
webAppName Il nome dell'app Web di App Service.
environmentName Nome dell'ambiente in cui eseguire la distribuzione, che viene creato automaticamente quando viene eseguito il processo di distribuzione.
projectRoot Cartella contenente il codice dell'app. Il valore è una variabile di sistema automatica.
pythonVersion Versione di Python da usare negli agenti di compilazione e distribuzione.

Fasi di build e distribuzione

La pipeline è costituita da fasi di compilazione e distribuzione.

Fase di costruzione

La fase di compilazione contiene un singolo processo eseguito nel sistema operativo definito nella vmImageName variabile , in questo caso ubuntu-latest.

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

La fase di build contiene un singolo job eseguito su un agente nel pool identificato dal parametro name.

È possibile specificare le funzionalità dell'agente con la demands parola chiave . Ad esempio, demands: python specifica che l'agente deve avere Installato Python. Per specificare un agente ospitato autonomamente per nome, è possibile usare demands: Agent.Name -equals <agent-name>.

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

Il processo contiene più passaggi:

  1. Prima di tutto, l'attività UsePythonVersion seleziona la versione di Python da usare, come definito nella pythonVersion variabile .

       - task: UsePythonVersion@0
          inputs:
            versionSpec: '$(pythonVersion)'
            displayName: 'Use Python $(pythonVersion)'
    
  2. Il passaggio successivo usa uno script che crea un ambiente Python virtuale e installa le dipendenze dell'app da requirements.txt. Il workingDirectory parametro specifica il percorso del codice dell'app.

       - script: |
            python -m venv antenv
            source antenv/bin/activate
            python -m pip install --upgrade pip
            pip install setuptools
            pip install  -r ./requirements.txt
          workingDirectory: $(projectRoot)
          displayName: "Install requirements"
    
  3. L'attività ArchiveFiles crea un archivio ZIP contenente l'app Web compilata.

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

    I parametri vengono impostati come segue:

    Parametro Descrizione
    rootFolderOrFile Posizione del codice dell'app.
    includeRootFolder Indica se includere la cartella radice nel file .zip . Impostare su false. Se impostato su true, il contenuto del file .zip viene inserito in una cartella denominata s e l'attività non riesce a trovare il codice dell'app.
    archiveType Tipo di archivio da creare. Impostare su zip.
    archiveFile Posizione del file .zip da creare.
    replaceExistingArchive Indica se sostituire un archivio esistente se il file esiste già. Impostare su true.
  4. Il .zip file carica quindi nella pipeline come artefatto denominato drop. La fase di distribuzione usa il file .zip per distribuire l'app.

        - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
          displayName: 'Upload package'
          artifact: drop
    
    • Il upload parametro imposta il percorso e il nome del file .zip da caricare.
    • Il artifact parametro imposta il nome dell'artefatto creato su drop.

Fase di distribuzione

La fase di distribuzione viene eseguita se la fase di compilazione viene completata correttamente. Le dependsOn parole chiave e condition definiscono questo comportamento.

  dependsOn: Build
  condition: succeeded()

La fase di distribuzione contiene un singolo processo di distribuzione configurato come indicato di seguito.

  - deployment: DeploymentJob
    pool:
      vmImage: $(vmImageName)
    environment: $(environmentName)
  • La deployment parola chiave indica che il processo è un processo di distribuzione destinato a un ambiente in cui eseguire la distribuzione. L'oggetto environment viene creato automaticamente nel progetto quando viene eseguito il processo.

  • Il pool parametro specifica il pool di agenti di distribuzione e usa il pool di agenti predefinito se non è specificato un oggetto name . L'agente viene eseguito nel sistema operativo definito nella vmImageName variabile , in questo caso ubuntu-latest.

  - deployment: DeploymentJob
    pool:
      name: <your-pool-name>
    environment: $(environmentName)
  • La deployment parola chiave indica che il processo è un processo di distribuzione destinato a un ambiente in cui eseguire la distribuzione. L'oggetto environment viene creato automaticamente nel progetto quando viene eseguito il processo.

  • Il pool parametro specifica il pool di agenti di distribuzione e deve contenere un agente con la possibilità di eseguire la versione di Python specificata nella pipeline.

La strategy parola chiave definisce la strategia di distribuzione.

  strategy:
    runOnce:
      deploy:
        steps:
  • La runOnce parola chiave specifica che il processo di distribuzione viene eseguito una sola volta.
  • La parola chiave deploy specifica il steps da eseguire nel processo di distribuzione.

steps in questa fase esegue le attività seguenti:

  1. UsePythonVersion@0 seleziona la versione di Python da usare, come nella fase di compilazione.
  2. AzureWebApp@1 distribuisce l'app Web e l'artefatto drop ZIP.
- task: AzureWebApp@1
    displayName: 'Deploy Azure Web App : <your-web-app-name>'
  inputs:
    azureSubscription: $(azureServiceConnectionId)
    appName: $(webAppName)
    package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
  • Il azureSubscription parametro contiene l'oggetto azureServiceConnectionId specificato nelle variabili della pipeline.
  • appName Contiene il valore della webAppName variabile.
  • package Specifica il nome e il percorso del file .zip da distribuire.

Inoltre, poiché il repository python-vscode-flask-tutorial contiene il comando di avvio dell'app in un file denominato startup.txt, è possibile specificare il comando di avvio dell'app aggiungendo il parametro : startUpCommand: 'startup.txt'.

Eseguire la pipeline

È ora possibile provare la pipeline.

  1. Nell'editor della pipeline selezionare Salva ed esegui.

  2. Nella schermata Salva ed esegui aggiungi un messaggio di commit, se necessario, quindi seleziona Salva ed esegui.

    È possibile monitorare l'esecuzione della pipeline selezionando Stages o Jobs nella pagina della pipeline Summary. Ogni processo e fase visualizza un segno di spunta verde quando viene completato correttamente. Se si verificano errori, vengono visualizzati nel riepilogo o nei passaggi del processo.

    Screenshot della sezione relativa alle fasi di riepilogo dell'esecuzione della pipeline.

    È possibile tornare rapidamente all'editor YAML selezionando i punti verticali in alto a destra nella pagina Riepilogo e selezionando Modifica pipeline.

    Screenshot del commento della pipeline di modifica da un report di build.

  3. Nel processo di distribuzione, selezionare l'attività Deploy Azure Web App per visualizzarne l'output.

    Screenshot dei passaggi della fase della pipeline.

  4. Dall'output, selezionare l'URL dopo App Service Application URL. L'app dovrebbe essere visualizzata nel modo seguente:

    Screenshot della vista dell'app di esempio in esecuzione su App Service.

Nota

Se la distribuzione di un'app non riesce a causa di una dipendenza mancante, il file direquirements.txt non è stato elaborato durante la distribuzione. Questo problema può verificarsi se si crea l'app Web direttamente nel portale anziché usare il az webapp up comando .

Il az webapp up comando imposta in modo specifico l'azione SCM_DO_BUILD_DURING_DEPLOYMENT di compilazione su true. Se si effettua il provisioning di un servizio app tramite il portale, questa azione non viene impostata automaticamente.

Per impostare questa azione:

  1. Nella pagina del portale per l'app Web selezionare Configurazione dal menu di spostamento a sinistra.
  2. Nella scheda Impostazioni applicazione selezionare Nuova impostazione applicazione.
  3. Nella finestra popup visualizzata impostare Nome su SCM_DO_BUILD_DURING_DEPLOYMENT, impostare Valore su truee selezionare OK.
  4. Selezionare Salva nella parte superiore della pagina Configurazione .
  5. Esegui di nuovo la pipeline. Le dipendenze dovrebbero ora essere installate durante la distribuzione.

Attivare un'esecuzione della pipeline

Questa pipeline viene impostata per l'esecuzione ogni volta che una modifica esegue l'accesso al repository di codice. Per attivare un'esecuzione della pipeline, eseguire il commit di una modifica nel repository. Ad esempio, è possibile aggiungere una nuova funzionalità all'app o aggiornare le dipendenze dell'app.

  1. Vai al repository GitHub della tua app.
  2. Apportare una modifica al codice, ad esempio la modifica del titolo dell'app.
  3. Eseguire il commit della modifica.
  4. Vai alla pipeline e verifica che sia stata creata una nuova esecuzione e che sia in esecuzione.
  5. Al termine dell'esecuzione, verificare che la modifica sia stata distribuita nella tua app Web.
  6. Nel portale di Azure, vai alla tua app Web e seleziona Centro di distribuzione dal menu di navigazione a sinistra.
  7. Selezionare la scheda Log e verificare che la nuova distribuzione sia elencata.

Distribuire app Django nel servizio app

È possibile usare Azure Pipelines per distribuire app Django nel servizio app in Linux se si usa un database separato. Non è possibile usare un database SQLite perché servizio app blocca il file db.sqlite3, impedendo sia letture che scritture. Questo comportamento non influisce sui database esterni.

Come illustrato nel processo di avvio del contenitore, il servizio app cerca automaticamente un file wsgi.py nel codice dell'app, che in genere contiene l'oggetto app. Se si vuole personalizzare il comando di avvio, usare il startUpCommand parametro nel AzureWebApp@1 passaggio del file di pipeline YAML.

Quando si usa Django, in genere si vuole eseguire la migrazione dei modelli di dati usando manage.py migrate dopo la distribuzione del codice dell'app. A questo scopo, è possibile aggiungere startUpCommand con uno script di post-distribuzione. Ad esempio, ecco la startUpCommand proprietà nell'attività 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'

Eseguire test sull'agente di compilazione

Come parte del processo di compilazione, è possibile eseguire test nel codice dell'app. I test vengono eseguiti nell'agente di compilazione, quindi è necessario installare le dipendenze in un ambiente virtuale nell'agente di compilazione. Dopo l'esecuzione dei test, eliminare l'ambiente virtuale di test prima di creare il file di.zip per la distribuzione.

Gli elementi di script seguenti illustrano questo processo. Posizionarli prima del compito ArchiveFiles@2 al file Azure-pipelines.yml. Per altre informazioni, vedere Eseguire script multipiattaforma.

# 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'

È anche possibile usare un'attività come PublishTestResults@2 per pubblicare i risultati del test nella pipeline. Per altre informazioni, vedere Eseguire test.

Pulire le risorse

Se le risorse di Azure create in questa esercitazione sono state completate, eliminarle per evitare di incorrere in ulteriori addebiti.

  • Eliminare il progetto Azure DevOps creato. L'eliminazione del progetto comporta anche l'eliminazione della pipeline e della connessione di servizio.
  • Eliminare il gruppo di risorse di Azure che contiene il servizio app e il piano di servizio app. Nella portale di Azure passare al gruppo di risorse, selezionare Elimina gruppo di risorse e seguire le istruzioni.
  • Eliminare l'account di archiviazione di Azure che gestisce il file system di Cloud Shell. Chiudere Cloud Shell, quindi trovare il gruppo di risorse che inizia con cloud-shell-storage-. Selezionare Elimina gruppo di risorse e seguire le istruzioni.