Azure Pipelines を使用して、Python Web アプリをビルドし、Azure App Service にデプロイします

Azure DevOps Services

継続的インテグレーションと継続的デリバリー (CI/CD) のために、Azure Pipelines を使用して Python Web アプリをビルドし、Linux 上の Azure App Service にデプロイします。 パイプラインはリポジトリへのコミットがあるたびに、自動的に Python Web アプリをビルドして App Service にデプロイします。

この記事では、次のことについて説明します。

  • Azure App Service で Web アプリを作成する。
  • Azure DevOps でのプロジェクトの作成。
  • DevOps プロジェクトを Azure に接続します。
  • Python 固有のパイプラインを作成します。
  • パイプラインを実行してアプリをビルドし、App Service のウェブ アプリにデプロイします。

前提条件

  • Azure サブスクリプション。 アカウントがない場合は、 無料アカウントを作成してください。
  • GitHub アカウント。 ない場合は、 無料で作成してください。
  • Azure DevOps Server。
  • セルフホステッド エージェント。 セルフホステッド エージェントを作成する必要がある場合は、「セルフホステッド エージェント」を参照してください。

アプリ コード用のリポジトリを作成する

https://github.com/Microsoft/python-sample-vscode-flask-tutorial にあるサンプル リポジトリを、GitHub アカウントにフォークします。

ローカル ホストで、GitHub リポジトリを複製します。 次のコマンドを使用し、 <repository-url> をフォークされたリポジトリの URL に置き換えます。

git clone <repository-url>

アプリをローカルにテストする

アプリをローカルにビルドおよび実行して、動作することを確認します。

  1. 複製したリポジトリ フォルダに変更します。

    cd python-sample-vscode-flask-tutorial
    
  2. アプリをビルドして実行する

    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. アプリを表示するには、ブラウザー ウィンドウを開き、 http://localhost:5000に移動します。 Visual Studio Flask Tutorial というタイトルが表示されることを確認します。

  4. 完了したら、ブラウザー ウィンドウを閉じ、 Ctrl+C で Flask サーバーを停止します。

Cloud Shell を開く

  1. Azure Portal ( https://portal.azure.com ) にサインインします。

  2. ポータルのツールバーの [Cloud Shell] ボタンを選択して、Azure CLI を開きます。

    Azure ポータルのツールバーの [Azure Cloud Shell] ボタンのスクリーンショット。

  3. Cloud Shell がブラウザーの下部に表示されます。 ドロップダウン メニューから、 [Bash] を選択します。

    Azure Cloud Shell のスクリーンショット。

  4. 作業するスペースを増やすには、最大化ボタンを選択します。

Azure App Service Web アプリを作成する

Azure ポータルの Cloud Shell から Azure App Service Web アプリを作成します。

ヒント

Cloud Shell に貼り付けるには、 Ctrl+Shift+V を使用するか、右クリックしてコンテキスト メニューから [貼り付け] を選択します。

  1. 次のコマンドを使用してリポジトリを複製します。 <repository-url> をフォークされたリポジトリの URL に置き換えます。

    git clone <repository-url>
    
  2. 複製されたリポジトリ フォルダーにディレクトリを変更して、 az webapp up コマンドによってアプリが Python アプリとして認識されるようにします。

    cd python-sample-vscode-flask-tutorial
    
  3. az webapp up コマンドを使用して、App Service のプロビジョニングとアプリの最初のデプロイの両方を行います。 <your-web-app-name> を Azure 全体で一意の名前に置き換えます。 通常は、個人または会社の名前と共に、アプリの識別子を使います (例: <your-name>-flaskpipelines)。 アプリの URL が、 <your-appservice>.azurewebsites.netになります。

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

    az webapp up コマンドの JSON 出力に、次の情報が表示されます。

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

    URLruntime_version の値をメモします。 パイプライン YAML ファイルで runtime_version を使用します。 URL は、Web アプリの URL です。 これを使用して、アプリが実行されていることを確認できます。

    Note

    az webapp up コマンドは、次の処理を実行します。

    • 既定の リソース グループを作成する。

    • 既定の App Service プランを作成する。

    • 指定された名前でアプリを作成 する。

    • ビルド自動化を有効にして、現在の作業ディレクトリからすべてのファイルを Zip デプロイ します。

    • 後で az webapp up またはプロジェクト フォルダー内の他の az webapp コマンドを使用してデプロイするときに再指定する必要がないように、パラメーターを .azure/config ファイルにローカルにキャッシュします。 キャッシュされた値は、既定で自動的に使用されます。

    コマンド パラメーターを使用して、既定のアクションを独自の値でオーバーライドできます。 詳細については、「az webapp up」を参照してください。

  4. python-sample-vscode-flask-tutorial アプリには、Web アプリの特定のスタートアップ コマンドを含む startup.txt ファイルがあります。 Web アプリの構成プロパティ startup-filestartup.txt に設定します。

    1. az webapp up コマンドの出力から、 resourcegroup 値をコピーします。

    2. リソース グループとアプリ名を使用して、次のコマンドを入力します。

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

    コマンドが完了すると、Web アプリのすべての設定を含む JSON 出力が表示されます。

  5. 実行中のアプリを表示するには、ブラウザーを開き、 az webapp up コマンド出力に示されている URL に移動します。 汎用ページが表示される場合は、App Service が起動するまで数秒待ってから、ページを更新します。 Visual Studio Flask Tutorial というタイトルが表示されることを確認します。

Azure DevOps プロジェクトの作成

新しい Azure DevOps プロジェクトを作成します。

  1. ブラウザで dev.azure.com にアクセスし、サインインします。
  2. 自分の組織を選択します。
  3. [新しいプロジェクト] を選択して新しいプロジェクトを作成します。または、組織内で最初のプロジェクトを作成する場合は、 [プロジェクトの作成] を選択します。
  4. プロジェクト名を入力します。
  5. プロジェクトの [可視性] を選択します。
  6. [作成] を選択します
  1. ブラウザーで、Azure DevOps Server にアクセスします。
  2. コレクションを選択します。
  3. [新しいプロジェクト] を選択して新しいプロジェクトを作成します。または、コレクション内で最初のプロジェクトを作成する場合は、 [プロジェクトの作成] を選択します。
  4. プロジェクト名を入力します。
  5. プロジェクトの [可視性] を選択します。
  6. [作成] を選択します

サービス プリンシパルの作成

サービス プリンシパルは、アプリケーション、ホステッド サービス、自動ツールを使用して Azure リソースにアクセスするために作成された ID です。 このアクセスはサービス プリンシパルに割り当てられているロールに制限されるため、どのリソースに、どのレベルでアクセスできるかを制御することができます。

サービス プリンシパルを作成するには、Cloud Shell (bash) に移動し、次のコマンドを実行します。 <service-principal-name> をサービス プリンシパルの名前に、 <your-subscription-id> をサブスクリプション ID に、 <your-resource-group> を Web アプリのリソース グループに置き換えます。

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

このコマンドは、次の例のような JSON オブジェクトを返します。

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

clientIdclientSecretsubscriptionId、および tenantId の値をメモします。 これらの値は、次のセクションでサービス接続を作成するために必要です。

サービス接続を作成する

サービス接続を使用すると、Azure Pipelines から外部およびリモート サービスへの認証済みアクセスを提供する接続を作成できます。 Azure App Service Web アプリにデプロイするには、Web アプリを含むリソース グループへのサービス接続を作成します。

  1. プロジェクト ページで、 [プロジェクト設定]を選択します。

    プロジェクト ダッシュボードの [プロジェクト設定] ボタンのスクリーンショット。

  2. メニューの [パイプライン] セクションで、 [サービス接続] を選択します。

  3. サービス接続の作成を選択します。

  4. [Azure Resource Manager] を選択し、 [次へ] を選択します。

    Azure Resource Manager サービス接続選択のスクリーンショット。

  5. 認証方法を選択し、 [次へ] を選択します。

  6. [新しい Azure サービス接続] ダイアログで、選択した認証方法に固有の情報を入力します。 認証方法の詳細については、「Azure Resource Manager サービス接続を使用して Azure に接続する」を参照してください。

    たとえば、 ワークロード ID フェデレーション (自動) または サービス プリンシパル (自動) 認証方法を使用している場合は、必要な情報を入力します。

    [新しいサービス接続] ダイアログ ボックスのスクリーン ショット。

    フィールド 説明
    スコープのレベル [サブスクリプション] を選択します。
    サブスクリプション Azure サブスクリプション名。
    リソース グループ Web アプリを含むリソース グループの名前。
    サービス接続名 接続のわかりやすい名前。
    すべてのパイプラインへのアクセス許可を与える すべてのパイプラインへのアクセスを許可するには、このオプションを選択します。
  7. [保存] を選択します。

新しい接続が [サービス接続] の一覧に表示され、Azure Pipeline で使用可能な状態になります。

  1. プロジェクト ページで、 [プロジェクト設定]を選択します。

    プロジェクト ダッシュボードの [プロジェクト設定] ボタンのスクリーンショット。

  2. メニューの [パイプライン] セクションで、 [サービス接続] を選択します。

  3. サービス接続の作成を選択します。

  4. [Azure Resource Manager] を選択し、 [次へ] を選択します。

    Azure Resource Manager サービス接続選択のスクリーンショット。

  5. [新しい Azure サービス接続] で、 サービス プリンシパル (手動) を選択し、 [次へ]を選択します

  6. 次のダイアログで、必要な情報を入力します。

    [新しいサービス接続] ダイアログ ボックスのスクリーン ショット。

    フィールド 説明
    Environment [Azure Cloud] を選択します。
    スコープのレベル [サブスクリプション] を選択します。
    サブスクリプション ID サブスクリプション ID。
    サブスクリプション名 Azure サブスクリプション名。
    サービス プリンシパル ID az ad sp create-for-rbac コマンドにより返される JSON からの appId 値。
    サービス プリンシパルのキー az ad sp create-for-rbac コマンドにより返される JSON からの password 値。
    テナント ID az ad sp create-for-rbac コマンドにより返される JSON からの tenant 値。
  7. [確認] を選択して、接続を確認します。

  8. サービス接続名を入力します。

  9. [すべてのパイプラインへのアクセス許可を与える] が選択されていることを確認します。

  10. [Verify and save] を選択します。

新しい接続が [サービス接続] の一覧に表示され、Azure Pipelines でプロジェクトから使用できるようになります。

セルフホステッド エージェントを構成する

独自のセルフホステッド エージェントを使用している場合は、Python を実行するようにエージェントを構成する必要があります。 セルフホステッド エージェントでは、Python バージョンのダウンロードはサポートされていません。 Python バージョンをプレインストールする必要があります。 完全なインストーラーを使用して、Python の pip 互換バージョンを取得します。

互換性のない問題を回避するには、Python のバージョンを Azure App Services Web アプリのランタイム バージョンと一致させる必要があります。 ランタイム バージョンは、 az webapp up コマンドの JSON 出力に表示されます。

目的の Python バージョンをセルフホステッド エージェントのツール キャッシュに追加して、タスクで使用できるようにする必要があります。 通常、ツール キャッシュはエージェントの _work/_tool ディレクトリの下にあります。または、環境変数 AGENT_TOOLSDIRECTORY でパスをオーバーライドすることもできます。 ツール ディレクトリの下に、Python のバージョンに基づいて次のディレクトリ構造を作成します。

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

バージョン番号は、1.2.3 の形式に従う必要があります。 プラットフォームは x86 または x64 です。 ツール ファイルは、解凍された Python バージョン ファイルである必要があります。 {platform}.complete は、 x86.completex64.complete のような 0 バイトのファイルで、ツールがキャッシュに正しくインストールされていることを示すだけです。

たとえば、64 ビット Windows マシンで Python 3.11 を使用している場合、ディレクトリ構造は次のようになります。

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

エージェントをホストしているコンピューターで使用する Python バージョンが既にある場合は、ツール キャッシュにファイルをコピーできます。 Python バージョンがない場合は、 Python Web サイトからダウンロードできます。

パイプラインを作成する

パイプラインを作成して Python Web アプリをビルドし、Azure App Service にデプロイします。 パイプラインの概念を理解するには、以下をご覧ください。

  1. 左側のナビゲーション メニューで、 [パイプライン]を選択します。

    プロジェクト ダッシュボードの [パイプライン] の選択のスクリーンショット。

  2. [Create Pipeline] を選択します。

    パイプライン リストの新しいパイプライン ボタンのスクリーンショット。

  3. [コードはどこにありますか?] ダイアログで、 [GitHub]を選択します。 GitHub へのサインインを求められる場合があります。

    コードの場所として [GitHub] を選択しているスクリーンショット。

  4. [リポジトリの選択] 画面で、フォークされたサンプル リポジトリを選択します。

    リポジトリ選択のスクリーンショット。

  5. 確認として、GitHub のパスワードをもう一度入力するように求められる場合があります。

  6. Azure Pipelines 拡張機能が GitHub にインストールされていない場合は、 Azure Pipelines 拡張機能をインストールするように求められます。

    Azure Pipelines 拡張機能を GitHub にインストールします。

    このページで、 [リポジトリ アクセス] セクションまで下にスクロールし、拡張機能をすべてのリポジトリにインストールするか、選択したリポジトリのみにインストールするかを選択し、 [承認してインストール] を選択します。

    GitHub の Azure Pipelines 拡張機能の [承認してインストール] のスクリーンショット。

  7. [パイプラインの構成] ダイアログで、 [Python to Linux Web App on Azure] (Python を Azure 上の Linux Web アプリに) を選択します。

  8. Azure サブスクリプションを選択し、 [続行] を選択します。

  9. 認証にユーザー名とパスワードを使用している場合は、ブラウザーが開き、Microsoft アカウントにサインインできます。

  10. ドロップダウン リストから Web アプリ名を選択し、 [検証と構成] を選択します。

Azure Pipelines によって azure-pipelines.yml ファイルが作成され、YAML パイプライン エディターに表示されます。 パイプライン ファイルにより、CI/CD パイプラインが一連の ステージジョブ、および ステップとして定義され、各ステップにはさまざまな タスクスクリプトの詳細情報が含まれます。 パイプラインを調べて、何が行われているかを確認します。 すべての既定の入力が自分のコードに適していることを確認します。

  1. ナビゲーション メニューで、 [パイプライン]を選択します。

    プロジェクト ダッシュボードの [パイプライン] の選択のスクリーンショット。

  2. [Create Pipeline] を選択します。

    [新しいパイプライン] ボタンのスクリーンショット。

  3. [コードはどこにありますか?] ダイアログで、 [GitHub Enterprise Server] を選択します。 GitHub へのサインインを求められる場合があります。

    コードの場所として [GitHub] を選択しているスクリーンショット。

  4. [リポジトリの選択] タブで、フォークされたサンプル リポジトリを選択します。

    リポジトリ選択のスクリーンショット。

  5. 確認として、GitHub のパスワードをもう一度入力するように求められる場合があります。

  6. Azure Pipelines 拡張機能が GitHub にインストールされていない場合は、 Azure Pipelines 拡張機能をインストールするように求められます。

    GitHub 上の Azure Pipelines 拡張機能のスクリーンショット。

    このページで、 [リポジトリ アクセス] セクションまで下にスクロールし、拡張機能をすべてのリポジトリにインストールするか、選択したリポジトリのみにインストールするかを選択し、 [承認してインストール] を選択します。

    GitHub の Azure Pipelines 拡張機能の [承認してインストール] のスクリーンショット。

  7. [パイプラインの構成] ダイアログで、 [スタート パイプライン]を選択します。

  8. azure-pipelines.yml ファイルの内容を次のコードに置き換えます。

    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. 以下のプレースホルダーを実際の値に置き換えます。

    プレースホルダー 説明
    <your-service-connection-name> 作成したサービス接続の名前。
    <your-web-app-name> Azure App Service Web アプリの名前。
    <your-pool-name> 使用するエージェント プールの名前。
    <your-python-version> エージェントで実行されている Python のバージョン。 このバージョンを Web アプリで実行されている Python バージョンと一致させることをお勧めします。 Web アプリのバージョンは、 az webapp up コマンドの JSON 出力に表示されます。

YAML パイプライン ファイル

以下では、YAML パイプライン ファイルについて説明します。 パイプライン YAML ファイル スキーマについては、「YAML スキーマ リファレンス」を参照してください。

パイプライン YAML ファイルの完全な例を次に示します。

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 セクションには、以下の変数が含まれています。

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'

変数 説明
azureServiceConnectionId Azure Resource Manager サービス接続の ID または名前。
webAppName Azure App Service Web アプリの名前。
vmImageName ビルド エージェントに使用するオペレーティング システムの名前。
environmentName デプロイ ステージで使用される環境の名前。 ステージ ジョブが実行されると、環境は自動的に作成されます。
projectRoot アプリ コードを含むルート フォルダー。
pythonVersion ビルドおよびデプロイ エージェントで使用する Python のバージョン。

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'
変数 説明
azureServiceConnectionId Azure Resource Manager サービス接続の名前。
webAppName Web アプリの名前。
environmentName デプロイ ステージで使用される環境の名前。
projectRoot アプリ コードを含むフォルダー。 値は自動システム変数です。
pythonVersion ビルドおよびデプロイ エージェントで使用する Python のバージョン。

ビルド ステージ

ビルド ステージには、vmImageName 変数で定義されているオペレーティング システムで実行される 1 つのジョブが含まれています。

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

ビルド ステージには、name パラメーターで識別されるプール内のエージェントで実行される 1 つのジョブが含まれています。 エージェントの機能は、 demands キーワードで指定できます。 たとえば、 demands: python エージェントに Python がインストールされている必要があることを指定します。 セルフホステッド エージェントを名前で指定するには、 demands: Agent.Name -equals <agent-name> キーワードを使用できます。

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

ジョブには複数のステップが含まれています。

  1. UsePythonVersion タスクは、使用する Python のバージョンを選択します。 バージョンは pythonVersion 変数で定義されます。

       - task: UsePythonVersion@0
          inputs:
            versionSpec: '$(pythonVersion)'
            displayName: 'Use Python $(pythonVersion)'
    
  2. この手順では、スクリプトを使用して仮想 Python 環境を作成し、 requirements.txt に含まれるアプリの依存関係をインストールします。 workingDirectory パラメーターは、アプリ コードの場所を指定します。

      - 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. ArchiveFiles タスクは、Web アプリを含む .zip アーカイブを作成します。 .zip ファイルは、 dropという名前の成果物としてパイプラインにアップロードされます。 .zip ファイルは、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
    
    パラメーター 説明
    rootFolderOrFile アプリ コードの場所。
    includeRootFolder ルート フォルダーを .zip ファイルに含めるかどうかを示します。 このパラメーターを false に設定します。そうしない場合は、 .zip ファイルの内容が s という名前のフォルダーに格納され、App Service on Linux コンテナーはアプリ コードを見つけられません。
    archiveType 作成するアーカイブの種類。 zip に設定します。
    archiveFile 作成する .zip ファイルの場所。
    replaceExistingArchive ファイルが既に存在する場合に、既存のアーカイブを置き換えるかどうかを示します。 true に設定します。
    upload アップロードする .zip ファイルの場所。
    artifact 作成する成果物の名前。

展開ステージ

デプロイ ステージは、ビルド ステージが正常に完了した場合に実行されます。 次のキーワードでこの動作を定義します。

  dependsOn: Build
  condition: succeeded()

デプロイ ステージには、次のキーワードで構成された 1 つのデプロイ ジョブが含まれています。

  - deployment: DeploymentJob
    pool:
      vmImage: $(vmImageName)
    environment: $(environmentName)
キーワード 説明
deployment ジョブが 環境を対象とする デプロイ ジョブ であることを示します。
pool デプロイ エージェント プールを指定します。 名前が指定されていない場合の既定のエージェント プール。 vmImage キーワードは、エージェントの仮想マシン イメージ用のオペレーティング システムを特定します
environment デプロイ先の環境を指定します。 ジョブが実行されると、環境はプロジェクト内に自動的に作成されます。
  - deployment: DeploymentJob
    pool:
      name: <your-pool-name>
    environment: $(environmentName)
キーワード 説明
deployment ジョブが 環境を対象とする デプロイ ジョブ であることを示します。
pool デプロイに使用するエージェント プールを指定します。 このプールには、パイプラインで指定された Python バージョンを実行する機能を持つエージェントが含まれている必要があります。
environment デプロイ先の環境を指定します。 ジョブが実行されると、環境はプロジェクト内に自動的に作成されます。

strategy キーワードは、デプロイ戦略の定義に使用されます。 runOnce キーワードは、デプロイ ジョブが 1 回実行されることを指定します。 deploy キーワードは、デプロイ ジョブで実行するステップを指定します。

  strategy:
    runOnce:
      deploy:
        steps:

パイプライン内の steps は以下のとおりです。

  1. UsePythonVersion タスクを使用して、エージェントで使用する Python のバージョンを指定します。 バージョンは pythonVersion 変数で定義されます。

     - task: UsePythonVersion@0
       inputs:
         versionSpec: '$(pythonVersion)'
       displayName: 'Use Python version'
    
  2. AzureWebApp@1 を使用して Web アプリをデプロイします。 このタスクは、パイプライン成果物 drop を 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
    
    パラメーター 説明
    azureSubscription 使用する Azure Resource Manager サービス接続の ID または名前。
    appName Web アプリの名前。
    package デプロイする .zip ファイルの場所。

    また、 python-vscode-flask-tutorial リポジトリには、 startup.txt という名前のファイルに同じスタートアップ コマンドが含まれているため、パラメーター startUpCommand: 'startup.txt'を追加してそのファイルを指定できます。

パイプライン内の steps は以下のとおりです。

  1. UsePythonVersion タスクを使用して、エージェントで使用する Python のバージョンを指定します。 バージョンは pythonVersion 変数で定義されます。

     - task: UsePythonVersion@0
       inputs:
         versionSpec: '$(pythonVersion)'
       displayName: 'Use Python version'
    
  2. AzureWebApp@1 を使用して Web アプリをデプロイします。 このタスクは、パイプライン成果物 drop を 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
    
    パラメーター 説明
    azureSubscription 使用する Azure Resource Manager サービス接続の ID または名前。
    appName Web アプリの名前。
    package デプロイする .zip ファイルの場所。

    また、 python-vscode-flask-tutorial リポジトリには、 startup.txt という名前のファイルに同じスタートアップ コマンドが含まれているため、パラメーター 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'
    
    パラメーター 説明
    azureSubscription 使用する Azure Resource Manager サービス接続の ID または名前。
    appName Web アプリの名前。
    package デプロイする .zip ファイルの場所。
    startUpCommand アプリのデプロイ後に実行するコマンド。 サンプル アプリでは、 startup.txtを使用しています。

パイプラインを実行する

これで、試してみる準備ができました。

  1. エディターで、 [保存して実行] を選択します。

  2. [保存して実行] ダイアログで、コミット メッセージを追加し、 [保存して実行] を選択します。

    パイプライン実行の概要でステージまたはジョブを選択することで、パイプラインの実行を監視できます。

    パイプライン実行の概要の [ステージ] セクションのスクリーンショット。

    各ステージおよびジョブが正常に完了すると、それぞれの横に緑色のチェックマークが付きます。 エラーが発生した場合は、概要またはジョブ ステップにそれらが表示されます。

    パイプライン ステージのステップのスクリーンショット。

    YAMLエディターにすばやく戻るには、 [概要] ページの右上にある縦に並んだドットを選択し、 [パイプラインの編集]を選択します。

    ビルド レポートの [パイプラインの編集] コメントのスクリーンショット。

  3. デプロイ ジョブから、 [Azure Web アプリのデプロイ] タスクを選択して、その出力を表示します。 デプロイされたサイトにアクセスするには、 Ctrl を押しながら、 App Service Application URLの後ろの URLを選択します。

    サンプル アプリを使用している場合、アプリは次のように表示されます。

    App Service で実行されているサンプル アプリの表示のスクリーンショット。

重要

依存関係がないためにアプリが失敗した場合、 requirements.txt ファイルはデプロイ中に処理されませんでした。 この動作は、この記事で示すように az webapp up コマンドを使うのではなく、ポータルで Web アプリを直接作成した場合に発生します。

az webapp up コマンドは、ビルド アクション SCM_DO_BUILD_DURING_DEPLOYMENTtrue に明示的に設定します。 ポータルを通じてアプリ サービスをプロビジョニングした場合、このアクションは自動的に設定されません。

次の手順でアクションが設定されます。

  1. Azure portal を開き、App Service を選んでから、 [構成] を選びます。
  2. [アプリケーションの設定] タブで、 [新しいアプリケーション設定]を選びます。
  3. 表示されるポップアップで、 [名前]SCM_DO_BUILD_DURING_DEPLOYMENTに設定し、 [値]trueに設定して、 [OK]を選びます。
  4. [構成] ページの上部にある [保存] を選択します。
  5. パイプラインを再実行します。 デプロイの間に依存関係がインストールされるようになるはずです。

パイプラインの実行をトリガーする

パイプライン実行をトリガーするには、リポジトリに変更をコミットします。 たとえば、新しい機能をアプリに追加したり、アプリの依存関係を更新したりできます。

  1. GitHub リポジトリに移動します。
  2. アプリのタイトルの変更など、コードに変更を加えます。
  3. 変更をリポジトリにコミットします。
  4. パイプラインに移動し、新しい実行が作成されたことを確認します。
  5. 実行が完了したら、新しいビルドが Web アプリにデプロイされていることを確認します。
    1. Azure Portal で、Web アプリに移動します。
    2. [デプロイ センター] を選択し、 [ログ] タブを選択します。
    3. 新しいデプロイが一覧表示されていることを確認します。

Django に関する考慮事項

別のデータベースを使用している場合は、Azure Pipelines を使用して Django アプリを Azure App Service on Linux にデプロイできます。 App Service は db.sqlite3 ファイルをロックし、読み取りと書き込みの両方を妨げるため、SQLite データベースを使うことはできません。 この動作は、外部データベースには影響しません。

App Service での Python アプリの構成の、コンテナー スタートアップ プロセスに関する記事で説明されているように、App Service はアプリ コード内で wsgi.py ファイルを自動的に検索します。このファイルには通常、アプリ オブジェクトが含まれます。 スタートアップ コマンドを何らかの方法でカスタマイズしたい場合は、前のセクションで説明したように、YAML パイプライン ファイルの AzureWebApp@1 ステップで、 startUpCommand パラメーターを使います。

Django を使うときは、通常、アプリ コードのデプロイ後に manage.py migrate を使ってデータ モデルを移行します。 この目的のために、デプロイ後のスクリプトを使用して startUpCommand を追加できます。 たとえば、AzureWebApp@1 タスクの startUpCommand プロパティを次に示します。

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

ビルド エージェントでテストを実行する

ビルド プロセスの一部として、アプリ コードでテストを実行することもできます。 テストはビルド エージェントで実行されるため、ビルド エージェントの仮想環境に依存関係をインストールする必要があります。 テストを実行した後、デプロイ用の .zip ファイルを作成する前に、仮想環境を削除します。 次のスクリプト要素は、このプロセスを示したものです。 これらを、 azure-pipelines.yml ファイルの ArchiveFiles@2 タスクの前に配置します。 詳しくは、「クロスプラットフォーム スクリプトを実行する」をご覧ください。

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

PublishTestResults@2 などのタスクを使用して、テスト結果をパイプラインに発行することもできます。 詳しくは、 Python アプリのビルドのテストの実行に関する記事をご覧ください。

リソースをクリーンアップする

このチュートリアルで作成した Azure リソースに料金が発生しないようにするには、次の手順に従います。

  • 作成したプロジェクトを削除します。 プロジェクトを削除すると、パイプラインとサービス接続が削除されます。

  • App Service と App Service プランを含む Azure リソース グループを削除します。 Azure ポータルで、リソース グループに移動し、 [リソース グループの削除] を選択して、プロンプトに従います。

  • Cloud Shell のファイル システムを維持するストレージ アカウントを削除します。 Cloud Shell を閉じ、 cloud-shell-storage- で始まるリソース グループに移動して、 [リソース グループの削除]を選択し、プロンプトに従います。

次のステップ