コンテナー化された Python アプリを App Service にデプロイする

チュートリアル シリーズのこのパートでは、コンテナー化された Python Web アプリケーションを Azure App Service Web App for Containers にデプロイする方法について説明します。 このフル マネージド サービスを使用すると、独自のコンテナー オーケストレーターを維持しなくても、コンテナー化されたアプリを実行できます。

App Service は、Docker Hub、Azure Container Registry、Azure Key Vault、およびその他の DevOps ツールと連携する継続的インテグレーション/継続的デプロイ (CI/CD) パイプラインを使用してデプロイを簡略化します。 このチュートリアルは、5 部構成のチュートリアル シリーズのパート 4 です。

この記事の最後には、Docker コンテナー イメージから実行されている、セキュリティで保護された運用対応の App Service Web アプリが用意されています。 このアプリでは、 システム割り当てマネージド ID を 使用して Azure Container Registry からイメージをプルし、Azure Key Vault からシークレットを取得します。

このサービス図では、この記事で説明するコンポーネントが強調表示されています。

デプロイ パスが強調表示されている Azure 上のコンテナー化された Python アプリのチュートリアルで使用するサービスのスクリーンショット。

Azure CLIコマンドは、Azure Cloud Shell または Azure CLI がインストールされているローカル コンピューターで実行できます。

重要

このチュートリアルのすべての CLI ベースの手順には、Azure Cloud Shell を使用します。

  • Azure アカウントで事前認証されているため、認証の問題が発生しません
  • 必要なすべてのAzure CLI拡張機能を含む
  • ローカル OS または環境に関係なく、一貫した動作を保証します
  • ローカル インストールは必要ありません。管理者権限のないユーザーに最適
  • ポータルからAzure サービスに直接アクセスできます。ローカルの Docker またはネットワークのセットアップは必要ありません
  • ローカル ファイアウォールまたはネットワーク構成の問題を回避する

RBAC 承認を使用して Key Vault を作成する

Azure Key Vault は、シークレット、API キー、接続文字列、証明書を格納するためのセキュリティで保護されたサービスです。 このスクリプトでは、 MongoDB 接続文字列 と Web アプリの SECRET_KEYを格納します。

従来のアクセス ポリシーではなく、Azure ロールを使用してアクセスを管理するために、ロールベースのアクセス制御 (RBAC) を使用するようにKey Vaultを構成します。 Web アプリは 、システム割り当てマネージド ID を 使用して、実行時にシークレットを安全に取得します。

手記

Key Vaultを早期に作成して、シークレットへのアクセスを試みる前にロールを割り当てられるようにします。 この方法は、ロールの割り当ての伝達遅延を回避するのにも役立ちます。 Key Vaultは App Service に依存しないため、早期にプロビジョニングすることで信頼性とシーケンス処理が向上します。

  1. az keyvault create コマンドを使用して、RBAC が有効なAzure Key Vaultを作成します。

    #!/bin/bash
    RESOURCE_GROUP_NAME="msdocs-web-app-rg"
    LOCATION="westus"
    KEYVAULT_NAME="${RESOURCE_GROUP_NAME}-kv"
    
    az keyvault create \
      --name "$KEYVAULT_NAME" \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --location "$LOCATION" \
      --enable-rbac-authorization true
    

App Service プランと Web アプリを作成する

App Service プランでは、Web アプリのコンピューティング リソース、価格レベル、リージョンを定義します。 Web アプリはコンテナー化されたアプリケーションを実行し、Azure Container Registry (ACR) とAzure Key Vaultに対して安全に認証するために使用するシステム割り当てマネージド ID を使用してプロビジョニングされます。

この手順では、次のタスクを実行します。

  • アプリサービス プランを作成する
  • マネージド ID を使用して Web アプリを作成する
  • 特定のコンテナー イメージを使用してデプロイするように Web アプリを構成する
  • ACR を使用した継続的デプロイの準備

手記

管理 ID はデプロイ時にのみ作成されるため、ACR または Key Vault へのアクセスを割り当てる前に、Web アプリを作成する必要があります。 また、作成時にコンテナー イメージを割り当てると、意図した構成でアプリが正しく起動します。

  1. az appservice plan create コマンドを使用して、アプリのコンピューティング環境をプロビジョニングします。

    #!/bin/bash
    APP_SERVICE_PLAN_NAME="msdocs-web-app-plan"
    
    az appservice plan create \
        --name "$APP_SERVICE_PLAN_NAME" \
        --resource-group "$RESOURCE_GROUP_NAME" \
        --sku B1 \
        --is-linux
    
  2. az webapp create コマンドを使用して Web アプリを作成します。 このコマンドでは、 システム割り当てマネージド ID も 有効にし、アプリが実行するコンテナー イメージを設定します。

    #!/bin/bash
    APP_SERVICE_NAME="msdocs-website-name" #APP_SERVICE_NAME must be globally unique as it becomes the website name in the URL `https://<website-name>.azurewebsites.net`.
    # Use the same registry name as in part 2 of this tutorial series.
    REGISTRY_NAME="msdocscontainerregistryname" #REGISTRY_NAME is the registry name you used in part 2 of this tutorial.
    CONTAINER_NAME="$REGISTRY_NAME.azurecr.io/msdocspythoncontainerwebapp:latest" #CONTAINER_NAME is of the form "yourregistryname.azurecr.io/repo_name:tag".
    
    az webapp create \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --plan "$APP_SERVICE_PLAN_NAME" \
      --name "$APP_SERVICE_NAME" \
      --assign-identity '[system]' \
      --deployment-container-image-name "$CONTAINER_NAME" 
    

    手記

    このコマンドを実行すると、次のエラーが表示されることがあります。

    No credential was provided to access Azure Container Registry. Trying to look up...
    Retrieving credentials failed with an exception:'Failed to retrieve container registry credentials. Please either provide the credentials or run 'az acr update -n msdocscontainerregistryname --admin-enabled true' to enable admin first.'
    

    このエラーは、Web アプリが管理者資格情報を使用して ACR にアクセスしようとしたが、管理者資格情報が既定で無効になっているために発生します。 このメッセージは無視してかまいません。 次の手順では、マネージド ID を使用して ACR で認証するように Web アプリを構成します。

認証されたユーザーに Key Vault Secrets Officer ロールを付与する

Azure Key Vault にシークレットを格納するには、スクリプトを実行するユーザーに Key Vault シークレット責任者 ロールが必要です。 このロールは、ボールト内でシークレットを作成および管理する権限を付与します。

この手順では、スクリプトによって、そのロールが現在認証されているユーザーに割り当てられます。 このユーザーは、MongoDB 接続文字列やアプリの SECRET_KEYなどのアプリケーション シークレットを安全に格納できます。

このロールの割り当ては、2 つの Key Vault に関連するロールの割り当ての最初です。 その後、Web アプリのシステム割り当てマネージド ID に、ボールトからシークレットを取得するためのアクセス権が付与されます。

Azure RBAC を使用すると、ID に基づいて安全で監査可能なアクセスを確保できるため、ハードコーディングされた資格情報を使用する必要はありません。

手記

ユーザーがキー コンテナーにシークレットを格納しようとする前にKey Vault Secrets Officer ロールをそのユーザーに割り当てます。 az ロールの割り当ての作成コマンドを使用して、Key Vaultをスコープとしてこの割り当てを行います。

  1. Key Vault スコープでロールを割り当てるには、az ロールの割り当て create コマンドを使用します。

    #!/bin/bash
    CALLER_ID=$(az ad signed-in-user show --query id -o tsv)
    echo $CALLER_ID # Verify this value retrieved successfully. In production, poll to verify this value is retrieved successfully.
    
    az role assignment create \
      --role "Key Vault Secrets Officer" \
      --assignee "$CALLER_ID" \
      --scope "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.KeyVault/vaults/$KEYVAULT_NAME"
    
    

マネージド ID を使用して ACR への Web アクセスを許可する

Azure Container Registry (ACR) からイメージを安全にプルするには、システム割り当てマネージド ID を使用するように Web アプリを構成します。 マネージド ID を使用すると、管理者の資格情報は必要なく、セキュリティで保護された資格情報のないデプロイをサポートできます。

このプロセスには、次の 2 つの主要なアクションが含まれます。

  • ACR にアクセスするときに Web アプリがマネージド ID を使用できるようにする
  • ターゲット ACR のその ID に AcrPull ロールを割り当てる
  1. この手順では、az webapp identity show コマンドを使用して、Web アプリのマネージド ID のプリンシパル ID (一意のオブジェクト ID) を取得します。 次に、acrUseManagedIdentityCreds を使用して true プロパティを に設定して、ACR 認証にマネージド ID を使用できるようにします。 次に、az role assignment create コマンドを使用して、AcrPull ロールを Web アプリのマネージド ID に割り当てます。 このロールは、レジストリからイメージをプルするアクセス許可を Web アプリに付与します。

    #!/bin/bash
    PRINCIPAL_ID=$(az webapp identity show \
      --name "$APP_SERVICE_NAME" \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --query principalId \
      -o tsv)
    echo $PRINCIPAL_ID # Verify this value retrieved successfully. In production, poll for successful 'AcrPull' role assignment using `az role assignment list`.    
    
    az webapp config set \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --name "$APP_SERVICE_NAME" \
      --generic-configurations '{"acrUseManagedIdentityCreds": true}'
    
    az role assignment create \
    --role "AcrPull" \
    --assignee "$PRINCIPAL_ID" \
    --scope "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.ContainerRegistry/registries/$REGISTRY_NAME"
    
    

Web アプリのマネージド ID にキーボールトへのアクセス権を付与する

Web アプリには、MongoDB 接続文字列や SECRET_KEYなどのシークレットにアクセスするためのアクセス許可が必要です。 これらのアクセス許可を付与するには、Key Vault Secrets User ロールを Web アプリの system 割り当てマネージド ID に割り当てます。

  1. この手順では、Web アプリのシステム割り当てマネージド ID の一意の識別子 (プリンシパル ID) を使用し、az role assignment create コマンドを使用して、Key Vault Secrets User ロールにより Web アプリに Key Vault へのアクセス権を付与します。

    #!/bin/bash
    
    az role assignment create \
    --role "Key Vault Secrets User" \
    --assignee "$PRINCIPAL_ID" \
    --scope "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.KeyVault/vaults/$KEYVAULT_NAME"
    

シークレットを Key Vault に格納する

アプリケーションでシークレットのハードコーディングを回避するには、MongoDB 接続文字列 と Web アプリの secret キーをAzure Key Vaultに格納します。 Web アプリは、マネージド ID を使用して実行時にこれらのシークレットに安全にアクセスできるため、資格情報をコードや構成に格納する必要はありません。

手記

このチュートリアルでは、接続文字列とシークレット キーのみをキー コンテナーに格納しますが、必要に応じて、MongoDB データベース名やコレクション名などの他のアプリケーション設定を Key Vault に格納することもできます。

  1. az cosmosdb キー リスト コマンドを使用して、MongoDB 接続文字列を取得します。 次に、az keyvault シークレット セット コマンドを使用して、接続文字列とランダムに生成されたシークレット キーの両方をKey Vaultに格納します。

    #!/bin/bash
    ACCOUNT_NAME="msdocs-cosmos-db-account-name"
    
    MONGO_CONNECTION_STRING=$(az cosmosdb keys list \
      --name "$ACCOUNT_NAME" \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --type connection-strings \
      --query "connectionStrings[?description=='Primary MongoDB Connection String'].connectionString" -o tsv)
    
    SECRET_KEY=$(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9')
    # This key is cryptographically secure, using OpenSSL’s strong random number generator.
    
    az keyvault secret set \
      --vault-name "$KEYVAULT_NAME" \
      --name "MongoConnectionString" \
      --value "$MONGO_CONNECTION_STRING"
    
    az keyvault secret set \
      --vault-name "$KEYVAULT_NAME" \
      --name "MongoSecretKey" \
      --value "$SECRET_KEY"
    

Key Vault シークレットを使用するように Web アプリを構成する

実行時にシークレットに安全にアクセスするには、Azure Key Vaultに格納されているシークレットを参照するように Web アプリを構成します。 Key Vault参照を使用して、システム割り当てマネージド ID を介してアプリの環境にシークレット値を挿入します。

この方法では、シークレットのハードコーディングを回避し、実行中に MongoDB 接続文字列やシークレット キーなどの機密値をアプリで安全に取得できます。

  1. az webapp config appsettings set コマンドを使用して、Key Vault シークレットを参照するアプリケーション設定を追加します。 具体的には、MongoConnectionStringMongoSecretKey アプリ設定を設定して、Key Vaultに格納されている対応するシークレットを参照します。

    #!/bin/bash
    MONGODB_NAME="restaurants_reviews"
    MONGODB_COLLECTION_NAME="restaurants_reviews"
    
    az webapp config appsettings set \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --name "$APP_SERVICE_NAME" \
      --settings \
          CONNECTION_STRING="@Microsoft.KeyVault(SecretUri=https://$KEYVAULT_NAME.vault.azure.net/secrets/MongoConnectionString)" \
          SECRET_KEY="@Microsoft.KeyVault(SecretUri=https://$KEYVAULT_NAME.vault.azure.net/secrets/MongoSecretKey)" \
          DB_NAME="$MONGODB_NAME" \
          COLLECTION_NAME="$MONGODB_COLLECTION_NAME"
    

ACR からの継続的デプロイを有効にする

継続的デプロイを有効にすると、Azure Container Registry (ACR) にプッシュするたびに、Web アプリによって最新のコンテナー イメージが自動的にプルされて実行されます。 この機能により、手動でのデプロイ手順が減り、アプリが最新の状態に保たれるようにします。

手記

次の手順では、ACR に Webhook を登録して、新しいイメージがプッシュされたときに Web アプリに通知します。

  1. az webapp deployment container config コマンドを使用して、ACR から Web アプリへの継続的デプロイを有効にします。

    #!/bin/bash
    az webapp deployment container config \
      --name "$APP_SERVICE_NAME" \
      --resource-group "$RESOURCE_GROUP_NAME" \
      --enable-cd true
    

継続的デプロイ用の ACR Webhook を登録する

デプロイを自動化するには、新しいコンテナー イメージがプッシュされるたびに Web アプリに通知する Webhook を Azure Container Registry (ACR) に登録します。 Webhook を使用すると、アプリは自動的に最新バージョンをプルして実行します。

Azure Container Registry (ACR) で構成した webhook は、新しいイメージが msdocspythoncontainerwebapp リポジトリにプッシュされるたびに、Web アプリの SCM エンドポイント (SERVICE_URI) に POST 要求を送信します。 このアクションにより、Web アプリが更新されたイメージをプルしてデプロイし、ACR と Azure App Service の間の継続的デプロイ パイプラインが完了します。

手記

Webhook URI は、次の形式に従う必要があります。
https://<app-name>.scm.azurewebsites.net/api/registry/webhook

。 URI エラーが発生した場合は、パスが正しいことを確認します。

  1. az acr webhook create コマンドを使用して webhook を登録し、push イベントでトリガーするように構成します。

    #!/bin/bash
    CREDENTIAL=$(az webapp deployment list-publishing-credentials \
        --resource-group "$RESOURCE_GROUP_NAME" \
        --name "$APP_SERVICE_NAME" \
        --query publishingPassword --output tsv)
    # Web app publishing credentials may not be available immediately. In production, poll until non-empty.   
    
    SERVICE_URI="https://$APP_SERVICE_NAME:$CREDENTIAL@$APP_SERVICE_NAME.scm.azurewebsites.net/api/registry/webhook"
    
    az acr webhook create \
      --name webhookforwebapp \
      --registry "$REGISTRY_NAME" \
      --scope msdocspythoncontainerwebapp:* \
      --uri "$SERVICE_URI" \
      --actions push
    
    

サイトを参照する

Web アプリが実行されていることを確認するには、 https://<website-name>.azurewebsites.netを開き、 <website-name> を App Service の名前に置き換えます。 レストラン レビュー サンプル アプリが表示されます。 初めて読み込むには少し時間がかかる場合があります。

サイトが表示されたら、レストランを追加してレビューを送信して、アプリが正しく機能していることを確認します。

手記

az webapp browse コマンドは Cloud Shell ではサポートされていません。 Cloud Shellを使用している場合は、ブラウザーを手動で開き、サイトの URL に移動します。

Azure CLIをローカルで使用している場合は、az webapp browse コマンドを使用して、既定のブラウザーでサイトを開きます。

az webapp browse --name $APP_SERVICE_NAME --resource-group $RESOURCE_GROUP_NAME

手記

az webapp browse コマンドは Cloud Shell ではサポートされていません。 ブラウザー ウィンドウを開き、代わりに Web サイトの URL に移動します。

デプロイのトラブルシューティング

サンプル アプリが表示されない場合は、次の手順を試してください。

  • コンテナーのデプロイと App Service については、Azure ポータルの Deployment Center / Logs ページを常に確認してください。 コンテナーがプルされて実行されていることを確認します。 コンテナの初回プルと起動には、しばらく時間がかかる場合があります。
  • App Service を再起動して、問題が解決するかどうかを確認します。
  • プログラミング エラーがある場合は、それらのエラーがアプリケーション ログに表示されます。 App Service の Azure portal ページで、[問題の診断と解決]/[アプリケーション ログ] を選択します。
  • サンプル アプリは、MongoDB 用 Azure Cosmos DB への接続に依存しています。 App Service に正しい接続情報を含むアプリケーション設定があることを確認します。
  • App Service でマネージド ID が有効になっており、デプロイ センターで使用されていることを確認します。 App Service の Azure portal ページで、App Service Deployment Center リソースに移動し、認証 がマネージド IDに設定されていることを確認します。
  • Webhook が Azure Container Registry で定義されていることを確認します。 Webhook を使用すると、App Service でコンテナー イメージをプルできます。 特に、サービス URI が "/api/registry/webhook" で終わることを確認します。 含まれていない場合は、ここで追加してください。
  • Azure Container Registry の SKU が異なると、Webhook の数など、機能も異なります。 既存のレジストリを再利用する場合は、「レジストリ SKU Basic で、リソースの種類 'webhooks' のクォータを超過しました。」というメッセージが表示されることがあります。 さまざまな SKU クォータとアップグレード プロセスの詳細を確認する: https://aka.ms/acr/tiers". このメッセージが表示された場合は、新しいレジストリを使用するか、使用中の レジストリ webhook の数を減らします。

次の手順

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