Azure SDK for Python を使用して Azure リソースに対して Azure でホストされるアプリを認証する

Azure App Service、Azure Virtual Machines、Azure Container Instances などのサービスを使用してアプリが Azure でホストされている場合、Azure リソースに対してアプリを認証する方法として推奨されるのは、マネージド ID を使用することです。

マネージド ID では、シークレット キーやその他のアプリケーション シークレットを使用しなくても他の Azure リソースに接続できるように、アプリの ID を提供します。 内部的には、Azure でアプリの ID と、接続が許可されているリソースを把握します。 Azure では、この情報を使用してアプリの Microsoft Entra トークンを自動的に取得し、アプリケーション シークレットを管理しなくても、他の Azure リソースに接続できるようにします。

マネージド ID の種類

マネージド ID には、次の 2 種類があります。

  • システム割り当てマネージド ID - この種類のマネージド ID は、Azure リソースによって提供され、Azure リソースに直接関連付けられます。 Azure リソースでマネージド ID を有効にすると、そのリソースのシステム割り当てマネージド ID が取得されます。 システム割り当てマネージド ID は、関連付けられている Azure リソースのライフサイクルに関連付けられます。 リソースが削除されると、その ID も Azure によって自動的に削除されます。 コードをホストしている Azure リソースのマネージド ID を有効にすればよいだけなので、これが最も使いやすい種類のマネージド ID です。
  • ユーザー割り当てマネージド ID - マネージド ID をスタンドアロンの Azure リソースとして作成することができます。 このアプローチが最もよく使用されるのは、ソリューションに複数の Azure リソースで実行される複数のワークロードがあり、すべてが同じ ID と同じアクセス許可を共有する必要がある場合です。 たとえば、ソリューションに複数の App Service と仮想マシンのインスタンスで実行されるコンポーネントがあり、それらのすべてが同じ Azure リソース セットにアクセスする必要がある場合、それらのリソース全体でユーザー割り当てマネージド ID を作成して使用することは理にかなっています。

この記事では、アプリのシステム割り当てマネージド ID を有効にして使用する手順について説明します。 ユーザー割り当てマネージド ID を使用する必要がある場合は、「ユーザー割り当てマネージド ID の管理」の記事を参照して、ユーザー割り当てマネージド ID の作成方法を確認してください。

1 - アプリをホストしている Azure リソースでマネージド ID を有効にする

最初の手順では、アプリをホストしている Azure リソースでマネージド ID を有効にします。 たとえば、Azure App Service を使用して Django アプリケーションをホストしている場合は、アプリをホストしている App Service Web アプリのマネージド ID を有効にする必要があります。 仮想マシンを使用してアプリをホストしている場合は、VM でマネージド ID を使用できるようにします。

Azure portal または Azure CLI を使用して、マネージド ID を Azure リソースに使用できるようにすることができます。

Azure CLI コマンドは、Azure Cloud Shell で、または Azure CLI がインストールされているワークステーション上で実行できます。

Azure リソースのマネージド ID を有効にするために使用される Azure CLI コマンドは、az <command-group> identity --resource-group <resource-group-name> --name <resource-name> の形式です。 一般的な Azure サービス向けの具体的なコマンドを次に示します。

az webapp identity assign --resource-group <resource-group-name> -name <web-app-name>

出力は次のようになります。

{
  "principalId": "99999999-9999-9999-9999-999999999999",
  "tenantId": "33333333-3333-3333-3333-333333333333",
  "type": "SystemAssigned",
  "userAssignedIdentities": null
}

principalId の値は、マネージド ID の一意の ID です。 次の手順でこれらの値が必要になるので、この出力のコピーを保管しておきます。

2 - マネージド ID にロールを割り当てる

次に、アプリに必要なロール (アクセス許可) を決定し、Azure でこれらのロールにマネージド ID を割り当てる必要があります。 マネージド ID には、リソース、リソース グループ、またはサブスクリプション スコープでロールを割り当てることができます。 次に、ほとんどのアプリケーションがすべてのAzureリソースを1つのリソースグループにグループ化するため、リソースグループスコープでロールを割り当てる例を示します。

マネージド ID には、az role assignment create コマンドを使用して、Azure でロールが割り当てられます。 担当者の場合は、手順 1 でコピーした principalId を使用します。

az role assignment create --assignee {managedIdentityprincipalId} \
    --scope /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName} \
    --role "{roleName}" 

サービス プリンシパルを割り当てることができるロール名を取得するには、az role definition list コマンドを使用します。

az role definition list \
    --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \
    --output table

たとえば、ID が 99999999-9999-9999-9999-999999999999 であるマネージド ID に、ID が 11111111-1111-1111-1111-111111111111 であるサブスクリプションに含まれる msdocs-python-sdk-auth-example リソース グループのすべてのストレージ アカウントの Azure Storage blob コンテナとデータへの読み取り、書き込み、および削除のアクセスを許可するには、次のコマンドを使用して、アプリケーション サービス プリンシパルを ストレージ BLOB データ共同作成者ロールに割り当てます。

az role assignment create --assignee 99999999-9999-9999-9999-999999999999 \
    --scope /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/msdocs-python-sdk-auth-example \
    --role "Storage Blob Data Contributor"

Azure CLI を使用してリソースまたはサブスクリプション レベルでアクセス許可を割り当てる方法については、「Azure CLI を使用して Azure ロールを割り当てる」を参照してください。

3 - アプリケーションに DefaultAzureCredential を実装する

コードが Azure で実行中であり、アプリをホストしている Azure リソースでマネージド ID が有効になっている場合、次の順序で使用する資格情報が DefaultAzureCredential により判断されます。

  1. 環境変数 AZURE_CLIENT_IDAZURE_TENANT_ID、および AZURE_CLIENT_SECRET または AZURE_CLIENT_CERTIFICATE_PATH そして任意で AZURE_CLIENT_CERTIFICATE_PASSWORD で定義されたサービス プリンシパルの環境をチェックします。
  2. ユーザー割り当てマネージド ID のキーワード パラメーターを確認します。 managed_identity_client_id パラメーターでクライアント ID を指定して、ユーザー割り当てマネージド ID を渡すことができます。
  3. ユーザー割り当てマネージド ID のクライアント ID で、環境変数で AZURE_CLIENT_ID を確認します。
  4. Azure リソースが有効になっている場合は、システム割り当てマネージド ID を使用します。

exclude_managed_identity_credentialキーワード パラメーターTrueを設定して、資格情報からマネージド ID を除外できます。

この記事では、Azure App Service の Web アプリにシステム割り当てマネージド ID を使用しているため、環境でマネージド ID を構成したり、パラメーターとして渡したりする必要はありません。 次の手順では、DefaultAzureCredential を使用する方法について説明します。

まず、アプリケーションに azure.identity パッケージを追加します。

pip install azure-identity

次に、アプリで Azure SDK クライアント オブジェクトを作成する Python コードでは、次のことが必要になります。

  1. DefaultAzureCredential モジュールから azure.identity クラスをインポートします。
  2. DefaultAzureCredential オブジェクトを作成します。
  3. Azure SDK クライアント オブジェクト コンストラクターに DefaultAzureCredential オブジェクトを渡します。

これらの手順の例を次のコードセグメントに示します。

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

# Acquire a credential object
token_credential = DefaultAzureCredential()

blob_service_client = BlobServiceClient(
        account_url="https://<my_account_name>.blob.core.windows.net",
        credential=token_credential)

Azure SDK for Python の認証の概要に関する記事で説明したように、DefaultAzureCredential では複数の認証方法をサポートし、実行時に使用される認証方法を決定します。 このアプローチのメリットは、環境固有のコードを実装することなく、異なる環境 (ローカルと運用環境) で異なる認証方法をアプリに使用できることです。 ローカルでの開発時に上記のコードをワークステーションで実行すると、DefaultAzureCredential は、環境設定で定義されたアプリケーション サービス プリンシパルを使用するか、開発者ツールの資格情報を使用して、他の Azure リソースを認証します。 したがって、同じコードを使用して、ローカル開発中と Azure へのデプロイ時の両方で Azure リソースに対してアプリを認証できます。