次の方法で共有


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

このチュートリアルでは、Django Web アプリを Azure App Service にデプロイします。 Web アプリはユーザーが割り当てたマネージド ID (パスワード不要接続) と Azure ロールベースのアクセス制御を使用して、Azure Storage と Azure Database for PostgreSQL - Flexible Server のリソースにアクセスします。 このコードでは、Python 用の Azure Identity クライアント ライブラリの DefaultAzureCredential クラスを使用しています。 この DefaultAzureCredential クラスは、App Service のマネージド ID が存在することを自動的に検出し、それを使用して他の Azure リソースにアクセスします。

このチュートリアルでは、ユーザー割り当てマネージド ID を作成し、App Service に割り当てて、データベースとストレージ アカウントのリソースにアクセスできるようにします。 システム割り当てマネージド ID の使用例については、「システム割り当てマネージド ID を使用して Flask Python Web アプリを作成して Azure にデプロイする」を参照してください。 ユーザー割り当てマネージド ID は、複数のリソースで使用でき、そのライフ サイクルは関連しているリソースのライフ サイクルと切り離されるために推奨されます。 マネージド ID を使用するためのベスト プラクティスについての詳細は、「マネージド ID のベスト プラクティスの推奨事項」をご参照ください。

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

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

Django サンプル アプリを使用して、このチュートリアルに従います。 サンプル アプリケーションを開発環境にダウンロードまたは複製します。

  1. サンプルを複製します。

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

    cd msdocs-django-web-app-managed-identity
    

認証コードを確認する

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

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

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

いずれの場合も、アプリが実行されるセキュリティ プリンシパルには、アプリが使用する Azure リソースごとに、アプリが求めるアクションを実行できるロールが割り当てられている必要があります。 このチュートリアルでは、Azure CLI コマンドを使用して、ユーザー割り当てマネージド ID を作成し、Azure 上のアプリに割り当てます。 次に、作成した ID に Azure ストレージ アカウントと Azure Database for PostgreSQL サーバーに対する適切なロールを手動で割り当てます。 最後に、Azure 上でアプリの AZURE_CLIENT_ID 環境変数を設定し、マネージド ID を使用するように DefaultAzureCredential を構成します。

アプリとそのランタイム環境でユーザー割り当てマネージド ID が構成され、データ ストアに適切なロールが割り当てられた後、DefaultAzureCredential を使用して必要な Azure リソースに認証することができます。

次のコードは、写真をアップロードするための BLOB ストレージ クライアントを作成するために./restaurant_review/views.pyで使用されます。 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")
conf.settings.DATABASES['default']['PASSWORD'] = 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"
    UA_NAME="UAManagedIdentityPythonTest$RAND_ID"
    

    重要

    ADMIN_PW には、次のうち3つのカテゴリから8~128文字が含まれている必要があります: 英大文字、英小文字、数字、記号。 ユーザー名またはパスワードを作成するとき、$文字を使用しないでください。 後で、これらの値を使用して環境変数を作成します。その際、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 \
      --active-directory-auth Enabled \
      --public-access 0.0.0.0
    

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

  4. サーバーの Microsoft Entra 管理者として Azure アカウントを追加するには、az postgres flexible-server ad-admin create コマンドを使用します。

    ACCOUNT_EMAIL=$(az ad signed-in-user show --query userPrincipalName --output tsv)
    ACCOUNT_ID=$(az ad signed-in-user show --query id --output tsv)
    echo $ACCOUNT_EMAIL, $ACCOUNT_ID
    az postgres flexible-server ad-admin create \
      --resource-group $RESOURCE_GROUP_NAME \
      --server-name $DB_SERVER_NAME \
      --display-name $ACCOUNT_EMAIL \
      --object-id $ACCOUNT_ID \
      --type User
    
  5. az postgres flexible-server firewall-rule create コマンドを使って、サーバーでファイアウォール規則を設定します。 この規則により、ローカル環境へのアクセスがサーバーに接続できるようになります。 (Azure Cloud Shell を使用する場合は、この手順を省略できます。)

    IP_ADDRESS=<your IP>
    az postgres flexible-server firewall-rule create \
       --resource-group $RESOURCE_GROUP_NAME \
       --name $DB_SERVER_NAME \
       --rule-name AllowMyIP \
       --start-ip-address $IP_ADDRESS \
       --end-ip-address $IP_ADDRESS
    

    IP アドレスを表示するツールやウェブサイトを使って、コマンドの <your IP> を置き換えます。 たとえば、What's My IP Address? のウェブサイトを使用できます。

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

    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 を作成してコードをデプロイする

サンプル アプリのルート フォルダーでこれらのコマンドを実行して、App Service を作成し、それにコードをデプロイします。

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

    az webapp up \
      --resource-group $RESOURCE_GROUP_NAME \
      --___location $LOCATION \
      --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"
    

ストレージ アカウントとコンテナーの作成

サンプル アプリでは、レビュー担当者から送信された写真がBLOBとしてAzure Storageに格納されます。

  • ユーザーがレビューで写真を送信すると、サンプル アプリはマネージド ID と DefaultAzureCredential を使用してイメージをコンテナーに書き込み、ストレージ アカウントにアクセスします。

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

このセクションでは、コンテナー内の BLOB へのパブリック読み取りアクセスを許可するストレージ アカウントとコンテナーを作成します。 後のセクションでは、ユーザー割り当てマネージド ID を作成し、ストレージ アカウントに BLOB を書き込むよう構成します。

  1. ストレージ アカウントを作成するには、az storage create コマンドを使用します。

    STORAGE_ACCOUNT_NAME="msdocsstorage$RAND_ID"
    az storage account create \
      --name $STORAGE_ACCOUNT_NAME \
      --resource-group $RESOURCE_GROUP_NAME \
      --___location $LOCATION \
      --sku Standard_LRS \
      --allow-blob-public-access true
    
  2. ストレージ アカウントに "photos" という名前のコンテナーを、az storage container create コマンドを使用して作成します。

    az storage container create \
      --account-name $STORAGE_ACCOUNT_NAME \
      --name photos \
      --public-access blob \
      --auth-mode login
    

    注記

    コマンドが失敗した場合 (たとえば、ストレージ アカウントのネットワーク 規則によって要求がブロックされる可能性があることを示すエラーが表示された場合)、次のコマンドを入力して、コンテナーを作成するアクセス許可を持つ Azure ロールが Azure ユーザー アカウントに割り当てられていることを確認します。

    az role assignment create --role "Storage Blob Data Contributor" --assignee $ACCOUNT_EMAIL --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.Storage/storageAccounts/$STORAGE_ACCOUNT_NAME"
    

    詳細については、「クイックスタート: Azure CLI を使用して BLOB を作成、ダウンロード、一覧表示する」を参照してください。 「所有者」、「共同作成者」、「ストレージ BLOB データ所有者」、「ストレージ BLOB データ共同作成者」など、いくつかの Azure ロールでは、ストレージ アカウントにコンテナーを作成できることに注意してください。

ユーザー割り当てマネージド ID を作成する

ユーザー割り当てマネージド ID を作成し、App Service に割り当てます。 マネージド ID は、データベースとストレージ アカウントにアクセスするために使用されます。

  1. az identity create コマンドを使用して、ユーザーに割り当てられたマネージド ID を作成し、クライアント ID を変数に出力して後で使用できるようにします。

    UA_CLIENT_ID=$(az identity create --name $UA_NAME --resource-group $RESOURCE_GROUP_NAME --query clientId --output tsv)
    echo $UA_CLIENT_ID
    
  2. az account show コマンドを使用してサブスクリプション ID を取得し、それをマネージド ID のリソース ID を構築するために使用できる変数に出力します。

    SUBSCRIPTION_ID=$(az account show --query id --output tsv)
    RESOURCE_ID="/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$UA_NAME"
    echo $RESOURCE_ID
    
  3. App Service にマネージド ID を割り当てるには、az webapp identity assign コマンドを使用します。

    export MSYS_NO_PATHCONV=1
    az webapp identity assign \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $APP_SERVICE_NAME \
        --identities $RESOURCE_ID
    
  4. az webapp config appsettings set コマンドを使用して、マネージド ID のクライアント ID やその他の構成情報を含む App Service アプリ設定を作成します。

    az webapp config appsettings set \
      --resource-group $RESOURCE_GROUP_NAME \
      --name $APP_SERVICE_NAME \
      --settings AZURE_CLIENT_ID=$UA_CLIENT_ID \
        STORAGE_ACCOUNT_NAME=$STORAGE_ACCOUNT_NAME \
        STORAGE_CONTAINER_NAME=photos \
        DBHOST=$DB_SERVER_NAME \
        DBNAME=restaurant \
        DBUSER=$UA_NAME
    

サンプル アプリでは、環境変数 (アプリ設定) を使用して、データベースとストレージ アカウントの接続情報を定義しますが、これらの値にパスワードは含まれません。 代わりに、認証は DefaultAzureCredential を使用してパスワードなしで行われます。

サンプル アプリ コードでは、ユーザーが割り当てたマネージド ID クライアント ID をコンストラクターに渡さずに、DefaultAzureCredential クラス コンストラクターを使用します。 このシナリオでは、AZURE_CLIENT_ID 環境変数を確認することが代替策となります。この環境変数はアプリ設定として定義します。

AZURE_CLIENT_ID 環境変数が存在しない場合、システム割り当てマネージド ID が構成されていればそれが使用されます。 詳細については、DefaultAzureCredential の紹介を参照してください。

マネージド ID 用にロールを作成します。

このセクションでは、マネージド ID のロールの割り当てを作成して、ストレージ アカウントとデータベースへのアクセスを有効にします。

  1. マネージド ID がストレージ アカウントにアクセスできるようにするために、`az role assignment create` コマンドを使用してロールの割り当てを作成します。

    export MSYS_NO_PATHCONV=1
    az role assignment create \
    --assignee $UA_CLIENT_ID \
    --role "Storage Blob Data Contributor" \
    --scope "/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCE_GROUP_NAME"
    

    このコマンドは、リソース グループへのロールの割り当てのスコープを指定します。 詳しくは、「ロールの割り当てについて」を参照ください。

  2. az postgres flexible-server execute コマンドを使用して Postgres データベースに接続し、同じコマンドを実行してマネージド アイデンティティに役割を割り当てます。

    ACCOUNT_EMAIL_TOKEN=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken)
    az postgres flexible-server execute \
      --name $DB_SERVER_NAME \
      --admin-user $ACCOUNT_EMAIL \
      --admin-password $ACCOUNT_EMAIL_TOKEN \
      --database-name postgres \
      --querytext "select * from pgaadauth_create_principal('"$UA_NAME"', false, false);select * from pgaadauth_list_principals(false);"
    

    コマンドの実行に問題がある場合は、PostgreSQL サーバーの Microsoft Entra 管理者としてユーザー アカウントを追加し、ファイアウォール規則で IP アドレスへのアクセスを許可していることを確認してください。 詳細については、「Azure PostgreSQL フレキシブル サーバーを作成する」セクションを参照のこと。

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

サンプル Python アプリでは、azure.identity パッケージとそのクラスを使用します。 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引数を追加すると、操作が完了する前にコマンドが戻ることを許可できます。

次のステップ

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

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