次の方法で共有


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

このチュートリアルでは、Python Flask コードをデプロイして、Azure App Service 上で実行されるウェブアプリを作成し、デプロイします。 Web アプリは、Azure ロールベースのアクセス制御を使用して、システムに割り当てられたマネージド ID (パスワードレス接続) により、Azure Storage と Azure Database for PostgreSQL - フレキシブル サーバーのリソースにアクセスします。 このコードでは、Python 用の Azure Identity クライアント ライブラリの DefaultAzureCredential クラスが使用されています。 この 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
    

認証コードを確認する

サンプル Web アプリは、2 つの異なるデータ ストアに対して認証を行う必要があります。

  • レビュー担当者から送信された写真を保存および取得する Azure Blob Storage サーバー。
  • Azure Database for PostgreSQL - レストランとレビューを保存するフレキシブル サーバー データベース。

両方のデータ ストアに対して認証を行うために、DefaultAzureCredential を使用します。 DefaultAzureCredential を使用すると、アプリは実行環境に応じて、異なるサービス プリンシパルの ID で動作するように設定できます。コードの変更は不要です。 たとえば、ローカル開発環境では、アプリは Azure CLI にサインインした開発者の ID で実行できます。一方、このチュートリアルのように Azure 環境では、そのアプリのシステム割り当てマネージド ID で実行できます。

いずれの場合も、アプリが実行されるセキュリティ プリンシパルには、アプリが使用する Azure リソースごとに、アプリが求めるアクションを実行できるロールが割り当てられている必要があります。 このチュートリアルでは、サービス コネクタを使用して、Azure 上のアプリでシステム割り当てマネージド ID を自動的に有効にし、その ID に Azure ストレージ アカウントと Azure Database for PostgreSQL サーバーに対する適切なロールを割り当てます。

システム割り当てマネージド ID が有効になり、データ ストアに対する適切なロールが割り当てられると、DefaultAzureCredential を使用して必要な Azure リソースに対して認証を行うことができます。

次のコードは、 で写真をアップロードするための BLOB ストレージ クライアントを作成するために使用されます。 DefaultAzureCredential のインスタンスがクライアントに渡され、クライアントはそのインスタンスを使用して、Azure ストレージに対して操作を実行するためのアクセス トークンを取得します。

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

azure_credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
    account_url=account_url,
    credential=azure_credential)

DefaultAzureCredential のインスタンスは、./azureproject/get_conn.py で Azure Database for PostgreSQL のアクセス トークンを取得するためにも使用されます。 この場合、資格情報インスタンスでget_tokenを呼び出し、適切なscopeの値を渡すことで、トークンが直接取得されます。 トークンはその後、呼び出し元に返される PostgreSQL 接続 URI でパスワードの代わりに使用されます。

azure_credential = DefaultAzureCredential()
token = azure_credential.get_token("https://ossrdbms-aad.database.windows.net")
conn = str(current_app.config.get('DATABASE_URI')).replace('PASSWORDORTOKEN', token.token)

Azure サービスを使用したアプリの認証の詳細については、「Azure SDK for Python を使用して Azure サービスに対して Python アプリを認証する方法」を参照してください。 環境に合わせて認証情報チェーンをカスタマイズする方法など、DefaultAzureCredential の詳細については、「DefaultAzureCredential の概要」を参照してください。

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 postgres 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. リポジトリ内の start.sh を使用するようにアプリサービスを構成するために、az webapp config set コマンドを使用します。

    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 コマンドを使用して、ブロブへの匿名読み取りアクセスを許可するようにストレージ アカウントを更新します。

    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) 
    

    メモ

    簡潔にするために、このコマンドはストレージ アカウント キーを使用してストレージ アカウントで承認します。 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引数を追加することで、操作が完了する前にコマンドが戻ることを許可できます。

次のステップ

  • Django Web アプリを作成し、ユーザーに割り当てられたマネージド ID を使用して Azure にデプロイする。

  • Python (Django または Flask) Web アプリを PostgreSQL を使用して Azure App Service に展開する