Flask Python Web アプリを作成し、システム割り当てマネージド ID を使用して Azure にデプロイする

このチュートリアルでは、Python Flask コードをデプロイして、Azure App Service で実行されている Web アプリを作成してデプロイします。 Web アプリは、Azure ロールベースのアクセス制御を使用したシステム割り当て マネージド ID (パスワードレス接続) を使用して、 Azure StorageAzure Database for PostgreSQL - フレキシブル サーバー のリソースにアクセスします。 このコードでは、 DefaultAzureCredential クラスの Python 用 Azure ID クライアント ライブラリ が使用されています。 この DefaultAzureCredential クラスは、App Service のマネージド ID が存在することを自動的に検出し、それを使用して他の Azure リソースにアクセスします。

Service Connector を使用して Azure サービスへのパスワードレス接続を構成することも、手動で構成することもできます。 このチュートリアルでは、Service Connector の使用方法について説明します。 パスワードレス接続の詳細については、「Azure サービスのパスワードレス接続」を参照してください。 Service Connector の詳細については、 Service Connector のドキュメントを参照してください。

このチュートリアルでは、Azure CLI を使用して Python web アプリを作成、デプロイする方法について説明します。 このチュートリアルのコマンドは、Bash シェルで実行するように記述されています。 ローカル環境や Azure Cloud Shell など、CLI がインストールされている Bash 環境であればチュートリアル コマンドを実行できます。 たとえば環境変数など、一部を変更して Windows コマンド シェルなどの他の環境でこれらのコマンドを実行できます。 ユーザー割り当てマネージド ID の使用例については、「ユーザー割り当てマネージド ID を使用して Django Web アプリを作成して Azure にデプロイする」を参照してください。

サンプル アプリを入手する

Flask フレームワークを使用したサンプルの Python アプリケーションを利用でき、このチュートリアルに沿って作業を進めるのに役立ちます。 サンプル アプリケーションのどれか 1 つをローカル ワークステーションにダウンロードまたはクローンします。

  1. Azure Cloud Shell セッションでサンプルを複製します。

    git clone https://github.com/Azure-Samples/msdocs-flask-web-app-managed-identity.git
    
  2. アプリケーション フォルダーに移動します。

    cd msdocs-flask-web-app-managed-identity
    

Azure PostgreSQL サーバーを作成する

  1. チュートリアルに必要な環境変数を設定します。

    LOCATION="eastus"
    RAND_ID=$RANDOM
    RESOURCE_GROUP_NAME="msdocs-mi-web-app"
    APP_SERVICE_NAME="msdocs-mi-web-$RAND_ID"
    DB_SERVER_NAME="msdocs-mi-postgres-$RAND_ID"
    ADMIN_USER="demoadmin"
    ADMIN_PW="ChAnG33#ThsPssWD$RAND_ID"
    

    重要

    ADMIN_PW には、次のうちの 3 つのカテゴリの、8 から 128 文字が含まれている必要があります。英大文字、英小文字、数字、英数字以外の文字のうち、3 つのカテゴリの文字が含まれている必要があります。 ユーザー名またはパスワードを作成するとき、 $ 文字は使用 しない でください。 後で、これらの値を使用して環境変数を作成しますが、Python アプリの実行に使用する Linux コンテナー内では、環境変数内の $ 文字に特殊な意味があります。

  2. az group create コマンドを使用して、リソース グループを作成します。

    az group create --location $LOCATION --name $RESOURCE_GROUP_NAME
    
  3. az postgreSQL flexible-server create コマンドを使用して、PostgreSQL サーバーを作成します。 (このコマンドと後続のコマンドでは、Bash Shell ('\') の行継続文字が使用されます。 必要に応じて、シェルの行継続文字を変更します)

    az postgres flexible-server create \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $DB_SERVER_NAME \
      --location $LOCATION \
      --admin-user $ADMIN_USER \
      --admin-password $ADMIN_PW \
      --sku-name Standard_D2ds_v4
    

    sku-name は価格レベルとコンピューティング構成の名前です。 詳しくは、「Azure Database for PostgreSQL の価格」をご覧ください。 利用可能な SKU を一覧表示するには、 az postgres flexible-server list-skus --location $LOCATIONを使用します。

  4. az postgres flexible-server execute コマンドを使用して、 restaurant という名前のデータベースを作成します。

    az postgres flexible-server execute \
      --name $DB_SERVER_NAME \
      --admin-user $ADMIN_USER \
      --admin-password $ADMIN_PW \
      --database-name postgres \
      --querytext 'create database restaurant;'
    

Azure App Service を作成してコードをデプロイする

  1. az webapp up コマンドを使用してアプリ サービスを作成します。

    az webapp up \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $APP_SERVICE_NAME \
      --runtime PYTHON:3.9 \
      --sku B1
    

    sku は App Service プランのサイズ (CPU、メモリ) とコストを定義します。 B1 (基本) サービス プランでは、Azure サブスクリプションに少額のコストが発生します。 App Service プラン一覧は、 [App Serviceの価格] のページをご覧ください。

  2. az webapp config set コマンドを使用して、リポジトリで start.sh を使用するようにアプリ サービスを構成します。

    az webapp config set \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $APP_SERVICE_NAME \
      --startup-file "start.sh"
    

Azure リソースへのパスワードレス コネクタを作成する

Service Connector コマンドは、マネージド ID と Azure ロールベースのアクセス制御を使用するように Azure Storage と Azure Database for PostgreSQL リソースを構成します。 このコマンドは、Web アプリをこれらのリソースに接続するアプリ設定を App Service で作成します。 コマンドからの出力には、パスワードレス機能を有効にするために実行されたサービス コネクタのアクションが一覧表示されます。

  1. az webapp connection create postgres-flexible コマンドを使用して PostgreSQL サービス コネクタを追加します。 この場合、システム割り当てマネージド ID は、ターゲット リソース PostgreSQL に対して Web アプリを認証するために使用されます。

    az webapp connection create postgres-flexible \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $APP_SERVICE_NAME \
      --target-resource-group $RESOURCE_GROUP_NAME \
      --server $DB_SERVER_NAME \
      --database restaurant \
      --client-type python \
      --system-identity
    
  2. az webapp connection create storage-blob コマンドを使用してストレージ サービス コネクタを追加します。

    また、このコマンドはストレージ アカウントを追加し、ストレージ アカウントに ストレージ Blob データ共同作成者 ロールを持つ Web アプリを追加します。

    STORAGE_ACCOUNT_URL=$(az webapp connection create storage-blob \
      --new true \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $APP_SERVICE_NAME \
      --target-resource-group $RESOURCE_GROUP_NAME \
      --client-type python \
      --system-identity \
      --query configurations[].value \
      --output tsv)
    STORAGE_ACCOUNT_NAME=$(cut -d . -f1 <<< $(cut -d / -f3 <<< $STORAGE_ACCOUNT_URL))
    

ストレージ アカウントにコンテナーを作成する

サンプル Python アプリは、レビュー担当者が送信した写真をストレージ アカウントのコンテナーに BLOB として格納します。

  • ユーザーがレビューと共に写真を送信すると、サンプル アプリは、システム割り当てマネージド ID を使用して、その画像をコンテナーに書き込み、認証と承認を行います。 最後のセクションで、この機能を構成しました。

  • ユーザーがレストランのレビューを表示すると、アプリは、関連付けられているレビューごとに、BLOB ストレージ内の写真へのリンクを返します。 ブラウザーで写真を表示するには、ストレージ アカウントで写真にアクセスできる必要があります。 BLOB データは、匿名 (非認証) アクセスによる読み取りを許可している必要があります。

セキュリティを強化するために、ストレージ アカウントは、既定で BLOB データへの匿名アクセスを無効にして作成されます。 このセクションでは、ストレージ アカウントで匿名の読み取りアクセスを有効にし、BLOB へのパブリック (匿名) アクセスを提供する 写真 という名前のコンテナーを作成します。

  1. az storage account update コマンドを使用して BLOB への匿名読み取りアクセス許可するように、ストレージ アカウントを更新します。

    az storage account update \
      --name $STORAGE_ACCOUNT_NAME \
      --resource-group $RESOURCE_GROUP_NAME \
      --allow-blob-public-access true
    

    ストレージ アカウントで匿名アクセスを有効にしても、個別の BLOB のアクセスには影響しません。 コンテナー レベルで BLOB へのパブリック アクセスを明示的に有効にする必要があります。

  2. az storage container create コマンドを使用して、ストレージ アカウントに photos という名前のコンテナーを作成します。 新しく作成されたコンテナー内の BLOB への匿名読み取り (パブリック) アクセスを許可します。

    az storage container create \
      --account-name $STORAGE_ACCOUNT_NAME \
      --name photos \
      --public-access blob \
      --account-key $(az storage account keys list --account-name $STORAGE_ACCOUNT_NAME \
          --query [0].value --output tsv) 
    

    Note

    簡潔にするために、このコマンドはストレージ アカウント キーを使用してストレージ アカウントで承認します。 Microsoft では、ほとんどの場合で Microsoft Entra ID と Azure (RBAC) ロールを使用することを推奨しています。 簡単な手順については、「クイックスタート: Azure CLI を使用して BLOB を作成、ダウンロード、一覧表示する」を参照してください。 「所有者」、「共同作成者」、「ストレージ BLOB データ所有者」、「ストレージ BLOB データ共同作成者」など、いくつかの Azure ロールでは、ストレージ アカウントにコンテナーを作成できることに注意してください。

BLOB データへの匿名の読み取りアクセスについて詳しくは、「コンテナーと BLOB 用の匿名読み取りアクセスを構成する」を参照してください。

Azure で Python Web アプリをテストする

サンプル Python アプリでは、 azure.identity パッケージとその DefaultAzureCredential クラスを使用します。 Azure でアプリが実行されると、 DefaultAzureCredential は App Services のマネージド ID が存在することを自動的に検出し、それを使用して他の Azure リソース (この場合はストレージと PostgreSQL) にアクセスします。 これらのリソースにアクセスするために、ストレージ キー、証明書、または資格情報を App Service に提供する必要はありません。

  1. デプロイされたアプリケーションの URL (http://$APP_SERVICE_NAME.azurewebsites.net) を参照します。

    アプリが開始されるまでに 1 から 2 分かかる場合があります。 既定のサンプル アプリ ページではない既定のアプリ ページが表示される場合は、少し待ってからブラウザーを最新の情報に更新します。

  2. サンプル アプリの機能をテストするには、レストランと、レストランの写真付きのレビューをいくつか追加します。

    レストランとレビューの情報は Azure Database for PostgreSQL に保存され、写真は Azure Storage に保存されます。 スクリーンショットの例を次に示します。

    Azure App Service、Azure PostgreSQL データベース、Azure Storage を使用したレストラン レビュー機能を示すサンプル アプリのスクリーンショット。

クリーンアップ

このチュートリアルでは、すべての Azure リソースが同じリソース グループに作成されました。 az group delete コマンドを使用してリソース グループを削除すると、リソース グループ内のすべてのリソースが削除され、アプリに使用されているすべての Azure リソースを最も速く削除することができます。

az group delete  --name $RESOURCE_GROUP_NAME 

必要に応じて、 --no-wait 引数を追加すると、操作が完了する前にコマンドから戻ることができます。

次のステップ