Teilen über


Verwenden von Azure Pipelines zum Erstellen und Bereitstellen einer Python Web-App für Azure App Service

Azure DevOps Services

Verwenden Sie Azure Pipelines für die kontinuierliche Integration und die kontinuierliche Bereitstellung (CI/CD), um eine Python-Web-App für Azure App Service auf Linux zu erstellen und bereitzustellen. Ihre Pipeline erstellt Ihre Python-Web-App automatisch und stellt sie App Service bereit, sobald ein Commit für das Repository erfolgt ist.

In diesem Artikel werden folgende Vorgehensweisen behandelt:

  • Erstellen einer Web-App in Azure App Service
  • Erstellen eines Projekts in Azure DevOps
  • Verbinden Sie Ihr DevOps-Projekt mit Azure.
  • Erstellen Sie eine Python-spezifische Pipeline.
  • Führen Sie die Pipeline aus, um Ihre App zu erstellen und für Ihre Web-App in App Service bereitzustellen.

Voraussetzungen

Erstellen eines Repositorys für Ihren App-Code

Forken Sie das Beispiel-Repository unter https://github.com/Microsoft/python-sample-vscode-flask-tutorial in Ihrem GitHub-Konto.

Klonen Sie auf Ihrem lokalen Host Ihr GitHub-Repository. Verwenden Sie den folgenden Befehl, und ersetzen Sie <repository-url> durch die URL Ihres geforkten Repositorys.

git clone <repository-url>

Lokales Testen Ihrer App

Erstellen und führen Sie die App lokal aus, um sicherzustellen, dass sie funktioniert.

  1. Wechseln Sie in den Ordner des geklonten Repositorys.

    cd python-sample-vscode-flask-tutorial
    
  2. Erstellen und Ausführen der App

    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. Um die App anzuzeigen, öffnen Sie ein Browserfenster und gehen Sie zu http://localhost:5000. Stellen Sie sicher, dass der Titel Visual Studio Flask Tutorial angezeigt wird.

  4. Wenn Sie fertig sind, schließen Sie das Browserfenster und beenden Sie den Flask-Server mit STRG+C.

Öffnen einer Cloud Shell

  1. Melden Sie sich unter https://portal.azure.com beim Azure-Portal an.

  2. Öffnen Sie die Azure CLI, indem Sie die Schaltfläche Cloud Shell auf der Symbolleiste des Portals auswählen.

    Screenshot der Schaltfläche Azure Cloud Shell auf der Symbolleiste des Azure-Portals.

  3. Die Cloud Shell wird am unteren Rand des Browsers angezeigt. Wählen Sie Bash aus dem Dropdown-Menü.

    Screenshot von Azure Cloud Shell.

  4. Damit Sie mehr Platz zum Arbeiten haben, wählen Sie die Schaltfläche Maximieren.

Erstellen einer Azure App Service Web-App

Erstellen Sie Ihre Azure App Service Web-App über die Cloud Shell im Azure-Portal.

Tipp

Verwenden Sie zum Einfügen in die Cloud Shell STRG+UMSCHALT+V, oder klicken Sie mit der rechten Maustaste und wählen Sie Einfügen aus dem Kontextmenü.

  1. Klonen Sie Ihr Repository mit folgendem Befehl, und ersetzen Sie <repository-url> durch die URL Ihres geforkten Repositorys.

    git clone <repository-url>
    
  2. Wechseln Sie in das Verzeichnis des geklonten Repositorys, damit der Befehl az webapp up die App als Python-App erkennt.

    cd python-sample-vscode-flask-tutorial
    
  3. Verwenden Sie den Befehl az webapp up, um sowohl App Service bereitzustellen als auch die Erstbereitstellung Ihrer App auszuführen. Ersetzen Sie <your-web-app-name> durch einen Namen, der in Azure eindeutig ist. In der Regel verwenden Sie einen persönlichen Namen oder Firmennamen zusammen mit einer App-ID, z. B. <your-name>-flaskpipelines. Die App-URL wird zu <your-appservice>.azurewebsites.net.

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

    Die JSON-Ausgabe des Befehls az webapp up zeigt:

    {
      "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>
    }
    

    Beachten Sie die Werte URL und runtime_version. Sie verwenden die runtime_version in der Pipeline-YAML-Datei. Die URL ist die URL Ihrer Web-App. Mit ihr können Sie überprüfen, ob die App ausgeführt wird.

    Hinweis

    Der Befehl az webapp up bewirkt Folgendes:

    • Erstellen einer Standardressourcengruppe

    • Erstellen eines App Service-Plans

    • Erstellen einer App mit dem angegebenen Namen

    • Stellen Sie alle Dateien aus dem aktuellen Arbeitsverzeichnis als ZIP bereit (mit aktivierter Build-Automatisierung).

    • Lokales Zwischenspeichern der Parameter in der Datei .azure/config, sodass Sie sie später bei der Bereitstellung mit az webapp up oder anderen az webapp-Befehlen aus dem Projektordner nicht erneut angeben müssen. Die zwischengespeicherten Werte werden standardmäßig automatisch verwendet.

    Sie können die Standardaktion mit Ihren eigenen Werten überschreiben, indem Sie die Befehlsparameter verwenden. Weitere Informationen finden Sie unter az webapp up.

  4. Die python-sample-vscode-flask-tutorial-App hat eine startup.txt-Datei, die den spezifischen Startbefehl für die Web-App enthält. Legen Sie die Konfigurationseigenschaft startup-file der Web-App auf startup.txt fest.

    1. Kopieren Sie aus der Ausgabe des Befehls az webapp up den Wert resourcegroup.

    2. Geben Sie den folgenden Befehl unter Verwendung der Ressourcengruppe und des Namens Ihrer App ein.

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

    Nach Beendigung des Befehls wird eine JSON-Ausgabe angezeigt, die alle Konfigurationseinstellungen für Ihre Web-App enthält.

  5. Um die ausgeführte App zu sehen, öffnen Sie einen Browser und gehen Sie zu URL (wird in der az webapp up Befehlsausgabe angezeigt). Wenn Sie eine generische Seite sehen, warten Sie ein paar Sekunden, bis App Service gestartet ist, und aktualisieren Sie dann die Seite. Stellen Sie sicher, dass der Titel Visual Studio Flask Tutorial angezeigt wird.

Ein Azure DevOps-Projekt erstellen

Erstellen Sie ein neues Azure DevOps-Projekt.

  1. Gehen Sie in einem Browser zu dev.azure.com, und melden Sie sich an.
  2. Wählen Sie Ihre Organisation aus.
  3. Erstellen Sie ein neues Projekt, indem Sie Neues Projekt oder Projekt erstellen wählen, wenn Sie das erste Projekt in der Organisation erstellen.
  4. Geben Sie einen Projektnamen ein.
  5. Wählen Sie die Sichtbarkeit für Ihr Projekt.
  6. Klicken Sie auf Erstellen.
  1. Gehen Sie in einem Browser zu Ihrem Azure DevOps-Server.
  2. Wählen Sie Ihre Sammlung.
  3. Erstellen Sie ein neues Projekt, indem Sie Neues Projekt oder Projekt erstellen wählen, wenn Sie das erste Projekt in der Sammlung erstellen.
  4. Geben Sie einen Projektnamen ein.
  5. Wählen Sie die Sichtbarkeit für Ihr Projekt.
  6. Klicken Sie auf Erstellen.

Erstellen eines Dienstprinzipals

Ein Dienstprinzipal ist eine Identität, die für den Zugriff auf Azure-Ressourcen mit Anwendungen, gehosteten Diensten und automatisierten Tools erstellt wird. Dieser Zugriff ist auf die dem Dienstprinzipal zugewiesenen Rollen beschränkt, sodass Sie steuern können, auf welche Ressourcen und auf welcher Ebene zugegriffen werden kann.

Um ein Dienstprinzipal zu erstellen, gehen Sie zur Cloud Shell (Bash) und führen Sie den folgenden Befehl aus. Ersetzen Sie <service-principal-name> durch einen Namen für Ihr Dienstprinzipal, <your-subscription-id> durch Ihre Abonnement-ID und <your-resource-group> durch die Ressourcengruppe für die Web-App.

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

Der Befehl gibt ein JSON-Objekt ähnlich dem folgenden Beispiel zurück:

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

Notieren Sie sich die Werte clientId, clientSecret, subscriptionId und tenantId. Sie benötigen diese Werte, um im nächsten Abschnitt eine Dienstverbindung zu erstellen.

Erstellen einer Dienstverbindung

Eine Dienstverbindung bietet Ihnen die Möglichkeit, eine Verbindung zu erstellen, die einen authentifizierten Zugriff von Azure Pipelines auf externe und Remote-Dienste ermöglicht. Um Ihre Azure App Service Web-App bereitzustellen, erstellen Sie eine Dienstverbindung zu der Ressourcengruppe, die die Web-App enthält.

  1. Wählen Sie auf der Projektseite Projekteinstellungen.

    Screenshot der Schaltfläche Projekteinstellungen auf dem Projekt-Dashboard.

  2. Wählen Sie Dienstverbindungen im Abschnitt Pipelines des Menüs.

  3. Wählen Sie Dienstleistungsverbindung erstellen.

  4. Wählen Sie Azure Resource Manager, und wählen Sie Weiter.

    Screenshot der Auswahl von Azure Resource Manager-Dienstverbindungen.

  5. Wählen Sie Ihre Authentifizierungsmethode, und wählen Sie Weiter.

  6. Geben Sie im Dialog Neue Azure-Dienstverbindung die für die ausgewählte Authentifizierungsmethode spezifischen Informationen ein. Weitere Informationen zu Authentifizierungsmethoden finden Sie unter Verbinden mit Azure über eine Azure Resource Manager-Dienstverbindung.

    Wenn Sie beispielsweise einen Workload-Identitätsverbund (automatisch) oder ein Dienstprinzipal (automatisch) als Authentifizierungsmethode verwenden, geben Sie die erforderlichen Informationen ein.

    Screenshot des Dialogfelds Neue Dienstverbindung.

    Feld Beschreibung
    Bereichsebene Wählen Sie Abonnement aus.
    Abonnement Den Namen Ihres Azure-Abonnements
    Ressourcengruppe Der Name der Ressourcengruppe, die Ihre Web-App enthält.
    Name der Dienstverbindung Ein beschreibender Name für die Verbindung.
    Zugriffsberechtigungen für alle Pipelines gewähren Wählen Sie diese Option, um den Zugriff auf alle Pipelines zu gewähren.
  7. Wählen Sie Speichern.

Die neue Verbindung erscheint in der Liste Dienstverbindungen und ist für die Verwendung in Azure Pipelines bereit.

  1. Wählen Sie auf der Projektseite Projekteinstellungen.

    Screenshot der Schaltfläche Projekteinstellungen auf dem Projekt-Dashboard.

  2. Wählen Sie Dienstverbindungen im Abschnitt Pipelines des Menüs.

  3. Wählen Sie Dienstleistungsverbindung erstellen.

  4. Wählen Sie Azure Resource Manager, und wählen Sie Weiter.

    Screenshot der Auswahl von Azure Resource Manager-Dienstverbindungen.

  5. Unter Neue Azure-Dienstverbindung wählen Sie Dienstprinzipal (manuell) und Weiter.

  6. Geben Sie im nächsten Dialogfeld die erforderlichen Informationen ein.

    Screenshot des Dialogfelds Neue Dienstverbindung.

    Feld Beschreibung
    Umgebung Wählen Sie Azure Cloud aus.
    Bereichsebene Wählen Sie Abonnement aus.
    Abonnement-ID Ihre Abonnement-ID.
    Abonnementname Den Namen Ihres Azure-Abonnements
    Dienstprinzipal-ID Der appId-Wert aus dem JSON-Objekt, das vom az ad sp create-for-rbac-Befehl zurückgegeben wird.
    Dienstprinzipalschlüssel Der password-Wert aus dem JSON-Objekt, das vom az ad sp create-for-rbac-Befehl zurückgegeben wird.
    Mandanten-ID Der tenant-Wert aus dem JSON-Objekt, das vom az ad sp create-for-rbac-Befehl zurückgegeben wird.
  7. Wählen Sie Überprüfen, um die Verbindung zu verifizieren.

  8. Geben Sie einen Dienstverbindungsnamen ein.

  9. Stellen Sie sicher, dass Zugriffsberechtigungen für alle Pipelines gewähren ausgewählt ist.

  10. Klicken Sie auf Verify and save.

Die neue Verbindung wird in der Liste Dienstverbindungen angezeigt und ist bereit für die Verwendung von Azure Pipelines aus dem Projekt.

Konfigurieren eines selbst gehosteten Agenten

Wenn Sie Ihren eigenen selbst gehosteten Agent verwenden, müssen Sie ihn so konfigurieren, dass er Python ausführen kann. Der Download von Python-Versionen wird von selbst gehosteten Agenten nicht unterstützt. Sie müssen die Python-Version vorinstallieren. Verwenden Sie das Installationsprogramm zur vollständigen Installation, um eine pip-kompatible Version von Python zu erhalten.

Um Inkompatibilitätsprobleme zu vermeiden, sollten Sie die Python-Version mit der Runtime-Version Ihrer Azure App Services Web-App abgleichen. Die Runtime-Version wird in der JSON-Ausgabe des Befehls az webapp up angezeigt.

Die gewünschte Python-Version muss zum Tool-Cache des gehosteten Agenten hinzugefügt werden, damit die Aufgabe sie verwenden kann. Normalerweise befindet sich der Tool-Cache im Verzeichnis _work/_tool des Agenten; alternativ kann der Pfad mit der Umgebungsvariablen AGENT_TOOLSDIRECTORY überschrieben werden. Legen Sie unter dem tools-Verzeichnis je nach Ihrer Python-Version die folgende Verzeichnisstruktur an:

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

Die Versionsnummer sollte dem Format von 1.2.3 entsprechen. Die Plattform sollte entweder x86 oder x64 sein. Bei den tool-Dateien sollte es sich um die entpackten Python-Versionsdateien handeln. {platform}.complete sollte eine 0-Byte-Datei sein, die wie x86.complete oder x64.complete aussieht und nur bedeutet, dass das Tool ordnungsgemäß im Cache installiert ist.

Wenn Sie z. B. Python 3.11 auf einer 64-Bit-Windows-Maschine verwenden, würde die Verzeichnisstruktur wie folgt aussehen:

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

Wenn Sie die Python-Version, die Sie verwenden möchten, bereits auf der Maschine haben, auf der Ihr Agent gehostet wird, können Sie die Dateien in den Tool-Cache kopieren. Wenn Sie nicht über die Python-Version verfügen, können Sie sie von der Python-Website herunterladen.

Erstellen einer Pipeline

Erstellen Sie eine Pipeline, um Ihre Python-Web-App zu erstellen und in Azure App Service bereitzustellen. Um die Konzepte der Pipeline zu verstehen, sehen Sie sich Folgendes an:

  1. Wählen Sie im linken Navigationsmenü Pipelines.

    Screenshot der Auswahl Pipelines auf dem Projekt-Dashboard.

  2. Wählen Sie Pipeline erstellen aus.

    Screenshot der Schaltfläche Neue Pipeline in der Pipeline-Liste.

  3. Im Dialog Wo ist Ihr Code wählen Sie GitHub. Sie werden möglicherweise aufgefordert, sich bei GitHub anzumelden.

    Screenshot der Auswahl von GitHub als Speicherort für Ihren Code.

  4. Auf der Seite Repository auswählen wählen Sie das geforkte Beispiel-Repository.

    Screenshot der Auswahl des Repositorys.

  5. Möglicherweise werden Sie aufgefordert, Ihr GitHub Kennwort zur Bestätigung erneut einzugeben.

  6. Wenn die Azure Pipelines-Erweiterung nicht auf GitHub installiert ist, fordert GitHub Sie auf, die Azure Pipelines-Erweiterung zu installieren.

    Installieren Sie die Azure Pipelines-Erweiterung auf GitHub.

    Scrollen Sie auf dieser Seite zum Abschnitt Repository-Zugriff, wählen Sie aus, ob die Erweiterung für alle Repositories oder nur für ausgewählte Repositories installiert werden soll, und wählen Sie dann Genehmigen und Installieren.

    Screenshot der Azure Pipelines-Erweiterung auf GitHub genehmigen und installieren.

  7. Im Dialog Konfigurieren Ihrer Pipeline wählen Sie Python zu Linux Web-App auf Azure.

  8. Wählen Sie Ihr Azure-Abonnement und Fortfahren.

  9. Wenn Sie Ihren Benutzendennamen und Ihr Kennwort zur Authentifizierung verwenden, öffnet sich ein Browser, mit dem Sie sich bei Ihrem Microsoft-Konto anmelden können.

  10. Wählen Sie den Namen Ihrer Web-App aus der Dropdown-Liste, und wählen Sie Validieren und Konfigurieren.

Azure Pipelines erstellt eine azure-pipelines.yml-Datei und zeigt sie im YAML Pipelines Editor an. Die Pipeline-Datei definiert Ihre CI/CD-Pipeline als eine Reihe von Phasen, Jobs und Schritten, wobei jeder Schritt die Details für verschiedene Aufgaben und Skripte enthält. Sehen Sie sich die Pipeline an, um herauszufinden, welche Vorgänge sie ausführt. Stellen Sie sicher, dass alle Standardeingaben für Ihren Code geeignet sind.

  1. Wählen Sie im Navigationsmenü Pipelines.

    Screenshot der Auswahl Pipelines auf dem Projekt-Dashboard.

  2. Wählen Sie Pipeline erstellen aus.

    Screenshot der Schaltfläche

  3. Im Dialog Wo ist Ihr Code wählen Sie GitHub Enterprise Server. Sie werden möglicherweise aufgefordert, sich bei GitHub anzumelden.

    Screenshot der Auswahl von GitHub als Speicherort für Ihren Code.

  4. Wählen Sie auf der Registerkarte Repository auswählen das geforkte Beispiel-Repository aus.

    Screenshot der Auswahl des Repositorys.

  5. Möglicherweise werden Sie aufgefordert, Ihr GitHub Kennwort zur Bestätigung erneut einzugeben.

  6. Wenn die Azure Pipelines-Erweiterung nicht auf GitHub installiert ist, fordert GitHub Sie auf, die Azure Pipelines-Erweiterung zu installieren.

    Screenshot der Azure Pipelines-Erweiterung auf GitHub.

    Scrollen Sie auf dieser Seite zum Abschnitt Repository-Zugriff, wählen Sie aus, ob die Erweiterung für alle Repositories oder nur für ausgewählte Repositories installiert werden soll, und wählen Sie dann Genehmigen und Installieren.

    Screenshot der Azure Pipelines-Erweiterung auf GitHub genehmigen und installieren.

  7. Wählen Sie im Dialog Pipeline konfigurieren die Option Starter-Pipeline.

  8. Ersetzen Sie den Inhalt der Datei azure-pipelines.yml durch den folgenden Code.

    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 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
    
        - 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. Ersetzen Sie die folgenden Platzhalter durch Ihre eigenen Werte:

    Platzhalter Beschreibung
    <your-service-connection-name> Der Name der von Ihnen erstellten Dienstverbindung.
    <your-web-app-name> Der Name Ihrer Azure App Service-Web-App.
    <your-pool-name> Den Namen des Agenten-Pools, den Sie verwenden möchten.
    <your-python-version> Die Python-Version, die auf Ihrem Agenten ausgeführt wird. Es ist ratsam, diese Version mit der Python-Version abzugleichen, die in Ihrer Web-App ausgeführt wird. Die Version der Web-App wird in der JSON-Ausgabe des Befehls az webapp up angezeigt.

YAML-Pipeline-Datei

Die folgende Erklärung beschreibt die YAML-Pipeline-Datei. Informationen über das Schema der YAML-Pipeline-Datei finden Sie unter YAML-Schema-Referenz.

Die vollständige Beispielpipeline-YAML-Datei wird unten gezeigt:

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

Variablen

Der variables-Abschnitt enthält die folgenden Variablen:

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 Beschreibung
azureServiceConnectionId Die ID oder der Name der Azure Resource Manager-Dienstverbindung.
webAppName Der Name der Azure App Service-Web-App.
vmImageName Der Name des Betriebssystems, das für den Build-Agent verwendet werden soll.
environmentName Der Name der Umgebung, die in der Bereitstellungsphase verwendet wird. Die Umgebung wird automatisch erstellt, wenn der Job für die Phase ausgeführt wird.
projectRoot Der Root-Ordner, der den Code der App enthält.
pythonVersion Die Python-Version, die für die Build- und Bereitstellungs-Agenten verwendet werden soll.

Der variables-Abschnitt enthält die folgenden Variablen:

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 Beschreibung
azureServiceConnectionId Der Name der Azure Resource Manager-Dienstverbindung.
webAppName Der Name der Web-App.
environmentName Der Name der Umgebung, die in der Bereitstellungsphase verwendet wird.
projectRoot Der Ordner, der den Code der App enthält. Der Wert ist eine automatische Systemvariable.
pythonVersion Die Python-Version, die für die Build- und Bereitstellungs-Agenten verwendet werden soll.

Buildphase

Die Build-Phase enthält einen einzelnen Job, der auf dem in der Variable vmImageName definierten Betriebssystem ausgeführt wird.

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

Die Build-Phase enthält einen einzelnen Job, der auf einem Agenten in dem Pool ausgeführt wird, der durch den Parameter name identifiziert wird. Sie können die Funktionalitäten des Agenten mit dem Schlüsselwort demands angeben. So gibt demands: python beispielsweise an, dass der Agent Python installiert haben muss. Um einen selbst gehosteten Agenten mit Namen anzugeben, können Sie das Schlüsselwort demands: Agent.Name -equals <agent-name> verwenden.

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

Der Job enthält mehrere Schritte:

  1. Die Aufgabe BenutzePythonVersion wählt die zu verwendende Python-Version aus. Die Version wird in der Variablen pythonVersion definiert.

       - task: UsePythonVersion@0
          inputs:
            versionSpec: '$(pythonVersion)'
            displayName: 'Use Python $(pythonVersion)'
    
  2. In diesem Schritt wird ein Skript verwendet, um eine virtuelle Python-Umgebung zu erstellen und die Abhängigkeiten der App zu installieren, die requirements.txt im Parameter enthalten sind. Der workingDirectory Parameter gibt den Speicherort des App-Codes an.

      - 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. Die Aufgabe ArchiveFiles erstellt das ZIP-Archiv, das die Web-App enthält. Die .zip-Datei wird als Artefakt mit dem Namen drop in die Pipeline hochgeladen. Die .zip-Datei wird in der Bereitstellungsphase verwendet, um die App in der Web-App bereitzustellen.

       - 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
    
    Parameter Beschreibung
    rootFolderOrFile Der Speicherort des Codes der App.
    includeRootFolder Gibt an, ob der Root-Ordner in die ZIP-Datei aufgenommen werden soll. Legen Sie diesen Parameter auf false fest, andernfalls wird der Inhalt der ZIP-Datei in einem Ordner namens s abgelegt und App Service im Linux-Container kann den App-Code nicht finden.
    archiveType Der Typ des zu erstellenden Archivs. Auf zip festlegen.
    archiveFile Der Speicherort der zu erstellenden ZIP-Datei.
    replaceExistingArchive Gibt an, ob ein vorhandenes Archiv ersetzt werden soll, wenn die Datei bereits existiert. Auf true festlegen.
    upload Der Speicherort der hochzuladenden ZIP-Datei.
    artifact Der Name des Artefakts, das erstellt werden soll.

Bereitstellungsphase

Die Bereitstellungsphase wird ausgeführt, wenn die Build-Phase erfolgreich abgeschlossen wurde. Die folgenden Schlüsselwörter definieren dieses Verhalten:

  dependsOn: Build
  condition: succeeded()

Die Bereitstellungsphase enthält einen einzelnen Job, der mit den folgenden Schlüsselwörtern konfiguriert ist:

  - deployment: DeploymentJob
    pool:
      vmImage: $(vmImageName)
    environment: $(environmentName)
Schlüsselwort Beschreibung
deployment Gibt an, dass es sich bei dem Job um einen Bereitstellungsjob für eine Umgebung handelt.
pool Gibt den Pool der Bereitstellungsagenten an. Der Standard-Agenten-Pool, wenn der Name nicht angegeben wird. Das Schlüsselwort vmImage identifiziert das Betriebssystem für das Image der virtuellen Maschine des Agenten
environment Gibt die Umgebung an, in der die Bereitstellung erfolgen soll. Die Umgebung wird automatisch in Ihrem Projekt erstellt, wenn der Job ausgeführt wird.
  - deployment: DeploymentJob
    pool:
      name: <your-pool-name>
    environment: $(environmentName)
Schlüsselwort Beschreibung
deployment Gibt an, dass es sich bei dem Job um einen Bereitstellungsjob für eine Umgebung handelt.
pool Gibt den Agenten-Pool an, der für die Bereitstellung verwendet werden soll. Dieser Pool muss einen Agenten enthalten, der in der Lage ist, die in der Pipeline angegebene Python-Version auszuführen.
environment Gibt die Umgebung an, in der die Bereitstellung erfolgen soll. Die Umgebung wird automatisch in Ihrem Projekt erstellt, wenn der Job ausgeführt wird.

Mit dem Schlüsselwort strategy wird die Bereitstellungsstrategie definiert. Das Schlüsselwort runOnce legt fest, dass der Bereitstellungs-Job einmal ausgeführt wird. Das Schlüsselwort deploy gibt die Schritte an, die in dem Bereitstellungs-Job ausgeführt werden sollen.

  strategy:
    runOnce:
      deploy:
        steps:

Die steps in der Pipeline sind:

  1. Verwenden Sie die Aufgabe UsePythonVersion, um die Python-Version anzugeben, die auf dem Agenten verwendet werden soll. Die Version wird in der Variablen pythonVersion definiert.

     - task: UsePythonVersion@0
       inputs:
         versionSpec: '$(pythonVersion)'
       displayName: 'Use Python version'
    
  2. Stellen Sie die Web-App mit der Aufgabe AzureWebApp@1 bereit. Mit dieser Aufgabe wird das Pipeline-Artefakt drop für Ihre Web-App bereitgestellt.

    - task: AzureWebApp@1
       displayName: 'Deploy Azure Web App : <your-web-app-name>'
       inputs:
          azureSubscription: $(azureServiceConnectionId)
          appName: $(webAppName)
          package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
    
    Parameter Beschreibung
    azureSubscription Die zu verwendende ID oder der Name der Dienstverbindung des Azure Resource Managers.
    appName Der Name der Web-App.
    package Der Speicherort der ZIP-Datei, die bereitgestellt werden soll.

    Da das python-vscode-flask-tutorial-Repository den gleichen Startbefehl in einer Datei namens startup.txt enthält, können Sie diese Datei auch durch Hinzufügen des Parameters angeben: startUpCommand: 'startup.txt'.

Die steps in der Pipeline sind:

  1. Verwenden Sie die Aufgabe UsePythonVersion, um die Python-Version anzugeben, die auf dem Agenten verwendet werden soll. Die Version wird in der Variablen pythonVersion definiert.

     - task: UsePythonVersion@0
       inputs:
         versionSpec: '$(pythonVersion)'
       displayName: 'Use Python version'
    
  2. Stellen Sie die Web-App mit der Aufgabe AzureWebApp@1 bereit. Mit dieser Aufgabe wird das Pipeline-Artefakt drop für Ihre Web-App bereitgestellt.

    - task: AzureWebApp@1
       displayName: 'Deploy Azure Web App : <your-web-app-name>'
       inputs:
          azureSubscription: $(azureServiceConnectionId)
          appName: $(webAppName)
          package: $(Pipeline.Workspace)/drop/$(Build.BuildId).zip
    
    Parameter Beschreibung
    azureSubscription Die zu verwendende ID oder der Name der Dienstverbindung des Azure Resource Managers.
    appName Der Name der Web-App.
    package Der Speicherort der ZIP-Datei, die bereitgestellt werden soll.

    Da das python-vscode-flask-tutorial-Repository den gleichen Startbefehl in einer Datei namens startup.txt enthält, können Sie diese Datei auch durch Hinzufügen des Parameters angeben: 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'
    
    Parameter Beschreibung
    azureSubscription Die zu verwendende ID oder der Name der Dienstverbindung des Azure Resource Managers.
    appName Der Name der Web-App.
    package Der Speicherort der ZIP-Datei, die bereitgestellt werden soll.
    startUpCommand Der Befehl, der ausgeführt werden soll, nachdem die App bereitgestellt wurde. In der Beispiel-App wird startup.txt verwendet.

Führen Sie die Pipeline aus.

Sie sind jetzt bereit, es auszuprobieren!

  1. Wählen Sie im Editor Speichern und Ausführen.

  2. Fügen Sie im Dialogfeld Speichern und Ausführen eine Commit-Nachricht hinzu, und wählen Sie dann Speichern und Ausführen.

    Sie können die Pipeline beim Ausführen beobachten, indem Sie die Phasen oder Jobs in der Zusammenfassung der Pipeline-Ausführung auswählen.

    Screenshot der Pipeline-Ausführung in der Zusammenfassung der Phasen.

    Sie können jede Phase und jeden Job mit einem grünen Häkchen überprüfen, wenn sie erfolgreich abgeschlossen wurden. Wenn Fehler auftreten, werden diese in der Zusammenfassung oder in den Job-Schritten angezeigt.

    Screenshot der Pipeline-Phasenschritte.

    Sie können schnell zum YAML-Editor zurückkehren, indem Sie die vertikalen Punkte oben rechts auf der Seite Zusammenfassung anklicken und Pipeline bearbeiten wählen:

    Screenshot des Kommentars zum Bearbeiten der Pipeline aus einem Build-Bericht.

  3. Wählen Sie im Bereitstellungs-Job die Aufgabe Azure-Web-App bereitstellen, um die Ausgabe anzuzeigen. Um den Bereitstellungs-Speicherort zu besuchen, halten Sie STRG gedrückt und wählen Sie die URL nach App Service Application URL.

    Wenn Sie die Beispiel-App verwenden, sollte die App wie folgt aussehen:

    Screenshot der Ansicht der Beispiel-App, die in App Service ausgeführt wird.

Wichtig

Wenn Ihre App aufgrund einer fehlenden Abhängigkeit fehlerhaft ist, wurde Ihre requirements.txt-Datei bei der Bereitstellung nicht verarbeitet. Dieses Verhalten tritt auf, wenn Sie die Web-App direkt im Portal erstellt haben, anstatt den Befehl az webapp up zu verwenden, wie in diesem Artikel beschrieben.

Der az webapp up-Befehl legt die Buildaktion SCM_DO_BUILD_DURING_DEPLOYMENT speziell auf true fest. Wenn Sie App Service über das Portal bereitgestellt haben, wird diese Aktion nicht automatisch festgelegt.

Mit den folgenden Schritten legen Sie die Aktion fest:

  1. Öffnen Sie das Azure-Portal, wählen Sie Ihren App Service und dann die Option Konfiguration aus.
  2. Wählen Sie unter der Registerkarte Anwendungseinstellungen die Option Neue Anwendungseinstellung aus.
  3. Legen Sie im daraufhin angezeigten Popup Name auf SCM_DO_BUILD_DURING_DEPLOYMENT fest, legen Sie Wert auf true fest, und wählen Sie dann OK aus.
  4. Klicken Sie oben auf der Seite Konfiguration auf Speichern.
  5. Erneutes Ausführen der Pipeline Ihre Abhängigkeiten sollten während der Bereitstellung installiert werden.

Auslösen einer Pipelineausführung

Um eine Pipeline auszulösen, committen Sie eine Änderung an das Repository. Sie können zum Beispiel eine neue Funktion zur App hinzufügen oder die Abhängigkeiten der App aktualisieren.

  1. Wechseln Sie zu Ihrem GitHub-Repository.
  2. Nehmen Sie eine Änderung am Code vor, wie z. B. die Änderung des Titels der App.
  3. Committen Sie die Änderung in Ihrem Repository.
  4. Gehen Sie zu Ihrer Pipeline, und überprüfen Sie, ob eine neue Ausführung durchgeführt wurde.
  5. Wenn die Ausführung abgeschlossen ist, vergewissern Sie sich, dass der neue Build in Ihrer Web-App bereitgestellt wurde.
    1. Navigieren Sie im Azure-Portal zu Ihrer Web-App.
    2. Wählen Sie Bereitstellungscenter, und wählen Sie die Registerkarte Protokolle.
    3. Überprüfen Sie, ob die neue Bereitstellung aufgelistet ist.

Überlegungen für Django

Sie können Azure Pipelines verwenden, um Django-Apps auf Azure App Service auf Linux bereitzustellen, wenn Sie eine separate Datenbank verwenden. Sie können keine SQLite-Datenbank verwenden, da App Service die Datei db.sqlite3 sperrt und damit sowohl Lese- als auch Schreibvorgänge verhindert. Dieses Verhalten wirkt sich nicht auf eine externe Datenbank aus.

Wie in Konfigurieren der Python-App in App Service – Containerstartprozess beschrieben, sucht die App Service-Instanz automatisch nach einer wsgi.py-Datei in Ihrem App-Code, die normalerweise das App-Objekt enthält. Wenn Sie den Startbefehl in irgendeiner Weise anpassen möchten, verwenden Sie den Parameter startUpCommand im Schritt AzureWebApp@1 Ihrer YAML-Pipelinedatei, wie im vorherigen Abschnitt beschrieben.

Bei Verwendung von Django möchten Sie die Datenmodelle in der Regel mithilfe von manage.py migrate nach der Bereitstellung des App-Codes migrieren. Zu diesem Zweck können Sie startUpCommand mit einem Bereitstellungsskript hinzufügen. Dies ist beispielsweise die startUpCommand-Eigenschaft in der Aufgabe 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'

Ausführen von Tests für den Build-Agent

Als Teil Ihres Build-Prozesses möchten Sie vielleicht Tests für Ihren App-Code ausführen. Tests werden auf dem Build-Agent ausgeführt, daher müssen Sie Ihre Abhängigkeiten in einer virtuellen Umgebung auf dem Build-Agent installieren. Löschen Sie nach Ausführung der Tests die virtuelle Umgebung, bevor Sie die ZIP-Datei für die Bereitstellung erstellen. Die folgenden Skriptelemente veranschaulichen diesen Prozess. Platzieren Sie sie vor der Aufgabe ArchiveFiles@2 in der Datei azure-pipelines.yml. Weitere Informationen finden Sie unter Ausführen plattformübergreifender Skripts.

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

Sie können auch eine Aufgabe wie PublishTestResults@2 verwenden, um die Testergebnisse in Ihrer Pipeline zu veröffentlichen. Weitere Informationen finden Sie unter Erstellen von Python-Apps – Ausführen von Tests.

Bereinigen von Ressourcen

Um zu vermeiden, dass Ihnen für die in diesem Tutorial erstellten Ressourcen auf Azure Kosten entstehen:

  • Löschen Sie das Projekt, das Sie erstellt haben. Durch das Löschen des Projekts werden die Pipeline und die Dienstverbindung gelöscht.

  • Löschen Sie die Azure-Ressourcengruppe, die App Service und den App Service-Plan enthält. Gehen Sie im Azure-Portal zu der Ressourcengruppe, wählen Sie Ressourcengruppe löschen, und folgen Sie den Anweisungen.

  • Löschen Sie das Speicherkonto, das das Dateisystem für die Cloud Shell verwaltet. Schließen Sie die Cloud Shell, und gehen Sie dann zu der Ressourcengruppe, die mit cloud-shell-storage- beginnt, wählen Sie Ressourcengruppe löschen, und folgen Sie den Anweisungen.

Nächste Schritte