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

このチュートリアルでは、Django Web アプリを Azure App Service にデプロイします。 Web アプリは、Azure ロールベースのアクセス制御を使用して、ユーザー割り当てマネージド ID (パスワードレス接続) を使用して、Azure StorageAzure Database for PostgreSQL - フレキシブル サーバー リソースにアクセスします。 このコードでは、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 リソースを作成する方法について説明します。 ローカル環境や Azure Cloud Shell または GitHub Codespaces など、CLI がインストールされている任意の環境でチュートリアル コマンドを実行できます。

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

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. チュートリアルに必要な環境変数を設定し、az group create コマンドを使用してリソース グループを作成します。

    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"
    
    az group create --location $LOCATION --name $RESOURCE_GROUP_NAME
    

    重要

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

  2. 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 を使用します。

  3. 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
    
  4. 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 サイトを使用できます。

  5. restaurantaz 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"
    

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

サンプル アプリでは、Azure Storage に Blob としてイメージが格納されます。 ストレージ アカウントは、コンテナーへのパブリック アクセスを許可するように構成されています。 アプリは、マネージド ID と DefaultAzureCredential を使用してストレージ アカウントにアクセスします。

  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
    

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

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

  1. az identity create コマンドを使用して、"UAManagedIdentityPythonTest" という名前のユーザー割り当てマネージド ID を作成し、後で使用するためにクライアント ID を変数に出力します。

    UAClientID=$(az identity create --name UAManagedIdentityPythonTest --resource-group $RESOURCE_GROUP_NAME --query clientId --output tsv)
    echo $UAClientID
    
  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/UAManagedIdentityPythonTest"
    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=$UAClientID \
        STORAGE_ACCOUNT_NAME=$STORAGE_ACCOUNT_NAME \
        STORAGE_CONTAINER_NAME=photos \
        DBHOST=$DB_SERVER_NAME \
        DBNAME=restaurant \
        DBUSER=UAManagedIdentityPythonTest
    

サンプル アプリでは、環境変数 (アプリ設定) を使用して、データベースとストレージ アカウントの接続情報を定義しますが、これらの値にパスワードは含まれません。 代わりに、認証はパスワードレスで 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 $UAClientID \
    --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('UAManagedIdentityPythonTest', false, false);select * from pgaadauth_list_principals(false);"
    

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

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

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

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

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

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

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

    Screenshot of the sample app showing restaurant review functionality using Azure App Service, Azure PostgreSQL Database, and Azure Storage.

クリーンアップ

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

az group delete  --name $RESOURCE_GROUP_NAME 

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

次のステップ