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

このチュートリアルでは、 Django Web アプリを Azure App Service にデプロイします。 Web アプリは、Azure ロールベースのアクセス制御を使用して、ユーザー割り当て マネージド ID (パスワードレス接続) を使用して、 Azure StorageAzure Database for PostgreSQL - フレキシブル サーバー リソースにアクセスします。 このコードでは、 DefaultAzureCredential クラスの Python 用 Azure ID クライアント ライブラリ が使用されています。 この 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
    

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 文字が含まれている必要があります。英大文字、英小文字、数字、英数字以外の文字のうち、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 \
      --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. az postgres flexible-server ad-admin create コマンドを使用して、サーバーの Microsoft Entra 管理者として Azure アカウントを追加します。

    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 アドレスを表示するツールや Web サイトを使って、コマンドの <your IP> を置き換えます。 たとえば、 IP アドレスを教えて Web サイトを使用できます。

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

サンプル アプリのルート フォルダーでこれらのコマンドを実行して、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. az storage container create コマンドを使用して、ストレージ アカウントに photos という名前のコンテナーを作成します。

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

    Note

    コマンドが失敗した場合 (たとえば、ストレージ アカウントのネットワーク 規則によって要求がブロックされる可能性があることを示すエラーが表示された場合)、次のコマンドを入力して、コンテナーを作成するアクセス許可を持つ 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. azidentitycreate コマンドを使用して、ユーザー割り当てのマネージド 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. az role assignment create コマンドを使用してストレージ アカウントへのアクセスを有効にするために、マネージド ID のロールの割り当てを作成します。

    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 データベースに接続し、同じコマンドを実行してマネージド ID にロールを割り当てます。

    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);"
    

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

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 引数を追加すると、操作が完了する前にコマンドから戻ることができます。

次のステップ