この記事では、Python アプリケーション コードで Azure クライアント ライブラリを使用して、Azure Blob ストレージ コンテナーにファイルをアップロードする方法を説明します。 この記事では、例: Azure Storage を作成するの中に示されているリソースが作成済みであることを前提としています。
特に記載のない限り、この記事で使用されているコマンドはいずれも、Linux と macOS の bash および Windows のコマンド シェルで同じように動作します。
1. ローカルの開発環境を設定する
まだ行っていない場合は、このコードを実行できる環境を設定します。 次のことをお試しください。
venv
またはお好みのツールを使用して Python 仮想環境を構成します。 仮想環境の使用を開始するには、必ずアクティブ化してください。 Python をインストールするには、「 Python のインストール」を参照してください。#!/bin/bash # Create a virtual environment python -m venv .venv # Activate the virtual environment source .venv/Scripts/activate # only required for Windows (Git Bash)
Conda環境を使用する。 Conda をインストールするには、「 Miniconda のインストール」を参照してください。
Visual Studio Code または GitHub Codespaces 内で Dev Container を使用します。
2. ライブラリ パッケージをインストールする
requirements.txt ファイルに、必要なクライアントライブラリのパッケージの行を追加して、ファイルを保存します。
azure-storage-blob
azure-identity
その後、ターミナルまたはコマンド プロンプトで、要件をインストールします。
pip install -r requirements.txt
3. アップロードするファイルを作成する
「sample-source.txt」という名前のソースファイルを作成します。 このファイル名は、コードで想定される名前です。
Hello there, Azure Storage. I'm a friendly file ready to be stored in a blob.
4. アプリ コードから Blob Storage を使用する
このセクションでは、例: Azure Storage を作成するの中で作成した BLOB コンテナー内のデータにアクセスする 2 つの方法を示します。 BLOB コンテナー内のデータにアクセスするには、アプリが Azure で認証され、コンテナー内のデータにアクセスする権限を持っている必要があります。 このセクションでは、これを行うための 2 つの方法について説明します。
Passwordless (推奨) メソッドは
DefaultAzureCredential
を使用してアプリを認証します。DefaultAzureCredential
はチェーン資格情報であり、開発者ツールの資格情報、アプリケーション サービス プリンシパル、マネージド ID など、一連の異なる資格情報を使用してアプリ(またはユーザー)を認証することができます。接続文字列方式では、接続文字列を使用してストレージ アカウントに直接アクセスします。
次のような理由から、可能な限りパスワードレス方式を使用することをお勧めします。
接続文字列方式では、接続元のエージェントをストレージ "アカウント" に対して認証します。そのアカウント内の個々のリソースに対して認証を行うわけではありません。 そのため、接続文字列では、許可する承認の範囲が必要以上に広くなってしまう可能性があります。
DefaultAzureCredential
を使用すると、Azure RBAC の使用を受けてアプリを実行する ID に、ストレージ リソースに対するさらにきめ細かい最小特権のアクセス許可を付与できます。接続文字列はアクセス情報をプレーン テキストで保持するため、適切に構築されていなかったり、セキュリティが適切に確保されていなかったりした場合に脆弱性のリスクが生じます。 そのような接続文字列が公開されれば、ストレージ アカウント内の広範なリソースへのアクセスに使用される可能性があります。
通常、接続文字列は環境変数に格納されるため、攻撃者から環境へのアクセスが可能になった場合、侵害を受ける危険性があります。 多くの
DefaultAzureCredential
でサポートされている資格情報の種類は、環境内にシークレットを格納する必要がありません。
DefaultAzureCredential
は、特定の方法に基づき、事前構成された資格情報チェーンです。 これは、最も一般的な認証フローおよび開発者ツールのほか、多くの環境をサポートするように設計されています。
DefaultAzureCredential
のインスタンスは、ランタイム環境、特定のよく知られている環境変数の値、および必要に応じてコンストラクターに渡されるパラメーターを組み合わせて、そのトークンを取得するために試しに使用する資格情報の種類を決定します。
次の手順では、アプリケーション サービス プリンシパルをアプリケーション ID として構成します。 アプリケーション サービス プリンシパルは、ローカル開発中の使用とオンプレミスでホストされるアプリでの使用の両方に適しています。 アプリケーション サービス プリンシパルを使用するように DefaultAzureCredential
を構成するには、環境変数 AZURE_CLIENT_ID
、AZURE_TENANT_ID
、および AZURE_CLIENT_SECRET
を設定します。
クライアント シークレットが構成されていることに注意してください。 これはアプリケーション サービス プリンシパルに必要ですが、シナリオによっては、環境変数にシークレットやパスワードを設定する必要のない資格情報を使用するように、DefaultAzureCredential
を構成することもできます。
たとえばローカル開発で、構成された環境変数を使用してトークンを取得できない場合、DefaultAzureCredential
は、Azure CLI などの開発ツールに (既に) サインインしているユーザーを使用して、トークンを取得しようとします。Azure でホストされているアプリの場合は、マネージド ID を使用するように DefaultAzureCredential
を構成することもできます。 いずれの場合も、アプリのコードに変更は必要なく、構成とランタイム環境のみが変わるだけです。
次のコードを含んだ use_blob_auth.py という名前のファイルを作成します。 ステップは、コメントで説明しています。
import os import uuid from azure.identity import DefaultAzureCredential # Import the client object from the SDK library from azure.storage.blob import BlobClient credential = DefaultAzureCredential() # Retrieve the storage blob service URL, which is of the form # https://<your-storage-account-name>.blob.core.windows.net/ storage_url = os.environ["AZURE_STORAGE_BLOB_URL"] # Create the client object using the storage URL and the credential blob_client = BlobClient( storage_url, container_name="blob-container-01", blob_name=f"sample-blob-{str(uuid.uuid4())[0:5]}.txt", credential=credential, ) # Open a local file and upload its contents to Blob Storage with open("./sample-source.txt", "rb") as data: blob_client.upload_blob(data) print(f"Uploaded sample-source.txt to {blob_client.url}")
参照リンク:
AZURE_STORAGE_BLOB_URL
という名前の環境変数を作成します。「pythonazurestorage12345」をストレージアカウントの名前で置き換えます。
AZURE_STORAGE_BLOB_URL
環境変数はこの例のみで使用されます。 Azure ライブラリでは使用されません。「az ad sp create-for-rbac」コマンドを使用して、アプリの新しいサービス プリンシパルを作成します。 このコマンドは、アプリのアプリ登録を同時に作成します。 サービス プリンシパルに、選択した名前を付けます。
az ad sp create-for-rbac --name <service-principal-name>
このコマンドの出力は次のようになります。 これらの値をメモするか、次の手順でこれらの値が必要になり、パスワード (クライアント シークレット) 値を再び表示できなくなるため、このウィンドウを開いたままにします。 ただし、必要に応じて、サービス プリンシパルや既存のパスワードを無効にせずに、後で新しいパスワードを追加できます。
{ "appId": "00001111-aaaa-2222-bbbb-3333cccc4444", "displayName": "<service-principal-name>", "password": "Aa1Bb~2Cc3.-Dd4Ee5Ff6Gg7Hh8Ii9_Jj0Kk1Ll2", "tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee" }
Azure CLI コマンドは、Azure Cloud Shell 内または Azure CLI がインストールされているワークステーション上で実行できます。
アプリケーション サービス プリンシパルの環境変数を作成します。
前のコマンドの出力値を使用して、次の環境変数を作成します。 これらの変数は、アプリケーション サービス プリンシパルを使用するように
DefaultAzureCredential
に指示します。-
AZURE_CLIENT_ID
→ アプリ ID の値です。 -
AZURE_TENANT_ID
→ テナント ID の値です。 -
AZURE_CLIENT_SECRET
→アプリ用に生成されたパスワード/資格情報。
-
コードを実行しようとします (意図的に失敗します)。
python use_blob_auth.py
「この要求には、このアクセス許可を使用して操作を実行する権限はありません」というエラーを確認します。このエラーは、使用しているローカル サービス プリンシパルに Blob コンテナーへのアクセス許可がまだないことが原因で表示されます。
「az role assignment create」 Azure CLI コマンドを使用して、BLOB コンテナーに対するストレージ BLOB データ共同作成者アクセス許可をサービス プリンシパルに付与します。
az role assignment create --assignee <AZURE_CLIENT_ID> \ --role "Storage Blob Data Contributor" \ --scope "/subscriptions/<AZURE_SUBSCRIPTION_ID>/resourceGroups/PythonAzureExample-Storage-rg/providers/Microsoft.Storage/storageAccounts/pythonazurestorage12345/blobServices/default/containers/blob-container-01"
--assignee
引数は、サービス プリンシパルを識別します。 <AZURE_CLIENT_ID> プレースホルダーをサービス プリンシパルのアプリIDに置き換えます。--scope
引数は、このロールの割り当てが適用される場所を特定します。 この例では、"ストレージ BLOB データ共同作成者" ロールを、"blob-container-01" というコンテナーのサービス プリンシパルに付与します。PythonAzureExample-Storage-rg
とpythonazurestorage12345
を、使用しているストレージ アカウントが含まれているリソース グループと、ストレージ アカウントの正確な名前に置き換えてください。 また、必要に応じて、BLOB コンテナーの名前を調整します。 間違った名前を使用すると、「入れ子になったリソースで要求された操作を実行できません」というエラーが表示されます。 親リソース 'pythonazurestorage12345' が見つかりません。" というエラーが表示されます。<AZURE_SUBSCRIPTION_ID> プレースホルダーをお使いの Azure サブスクリプション ID に置き換えます。 (az account show コマンドを実行し、出力の
id
プロパティからお使いのサブスクリプション ID を取得できます。)
ヒント
bash シェルを使用した際に、ロール割り当てコマンドが「接続アダプターが見つかりません」というエラーを返す場合、パス変換を回避するために、環境変数 MSYS_NO_PATHCONV を 1 に設定してください。 詳細については、この課題を参照してください。
アクセス許可が反映されるまで 1、2 分待機した後、コードをもう一度実行して、今度は動作することを確認します。 アクセス許可のエラーが再度表示された場合は、もう少し待ってから、もう一度コードを試してください。
ロールの割り当てについての詳細は、「Azure CLI を使用してロールのアクセス許可を割り当てる方法」に関するページを参照してください。
重要
前の手順では、アプリはアプリケーション サービス プリンシパルで実行されました。 アプリケーション サービス プリンシパルの構成には、クライアント シークレットが必要です。 ただし、同じコードを使用して、環境でパスワードやシークレットを明示的に構成する必要のない、異なる資格情報の種類でアプリを実行することもできます。 たとえば、開発中は、DefaultAzureCredential
は、Azure CLI 経由でサインインする際に使用する資格情報のような、開発者ツールの資格情報を使用できます。また、Azure でホストされているアプリの場合は、マネージド ID を使用できます。 詳細については、「Azure SDK for Python を使用して Azure サービスに対して Python アプリケーションを認証する方法」を参照してください。
5. BLOB の作成を確認する
どちらかの方法のコードを実行した後、Azure portal にアクセスし、BLOB コンテナーの中に移動して、sample-source.txt ファイルと同じ内容の新しい BLOB が sample-blob-{random}.txt という名前で存在することを確認します。
BLOB コンテナーの Azure ポータル ページ、アップロード済みのファイルを表示
AZURE_STORAGE_CONNECTION_STRING
という名前の環境変数を作成した場合は、Azure CLI を使用して az storage blob list コマンドを利用し、その Blob が存在するかどうかを確認できます。
az storage blob list --container-name blob-container-01
パスワードレス認証を使用する手順に従った場合、ストレージ アカウントの接続文字列を用いて、そのパラメーターを前述のコマンドに追加できます。 接続文字列を取得するには、「az storage account show-connection-string」コマンドを使用します。
az storage account show-connection-string --resource-group PythonAzureExample-Storage-rg --name pythonazurestorage12345 --output tsv
--connection-string
パラメーターの値として接続文字列全体を使用します。
注
コンテナーに対して "Storage Blob Data Contributor" の役割が Azure ユーザー アカウントに割り当てられている場合、次のコマンドを使用してコンテナー内の BLOB を一覧表示できます。
az storage blob list --container-name blob-container-01 --account-name pythonazurestorage12345 --auth-mode login
6.リソースをクリーンアップする
この例を用いたリソースグループおよびストレージリソースを保持する必要がない場合は、az group delete コマンドを実行します。 リソース グループではサブスクリプションに継続的な料金は発生しませんが、リソース グループ内のストレージ アカウントなどのリソースには引き続き料金が発生する可能性があります。 アクティブに使用していないグループをクリーンアップすることをお勧めします。
--no-wait
引数を使用すると、操作が完了するまで待機せずに直ちにコマンドが戻ります。
az group delete -n PythonAzureExample-Storage-rg --no-wait
あなたは ResourceManagementClient.resource_groups.begin_delete
メソッドを使用してコードからリソース グループを削除することもできます。
例: リソース グループを作成する のコードでは、使用方法を示しています。
パスワードレス認証を使用する手順に従った場合は、作成したアプリケーション サービス プリンシパルを削除することが推奨されます。 「az ad app delete」コマンドを使用できます。 <AZURE_CLIENT_ID> プレースホルダーをサービス プリンシパルのアプリ ID で置き換えます。
az ad app delete --id <AZURE_CLIENT_ID>