例: Python 用 Azure ライブラリを使用して Azure Storage にアクセスする
この記事では、Python アプリケーション コードで Azure クライアント ライブラリを使用して、Azure Blob ストレージ コンテナーにファイルをアップロードする方法を説明します。 この記事では、「例: Azure Storage の作成」に示されているリソースを作成していることを前提としています。
特に記載のない限り、この記事で使用されているコマンドはいずれも、Linux と macOS の bash および Windows のコマンド シェルで同じように動作します。
1: ローカルの開発環境を設定する
まだ行っていない場合は、このコードを実行できる環境を設定します。 次のことをお試しください。
venv
または任意のツールを使用して Python 仮想環境を構成します。 仮想環境は、ローカルまたは Azure Cloud Shell で作成し、そこでコードを実行できます。 仮想環境の使用を開始するには、必ず仮想環境をアクティブにします。Conda 環境を使用します。
Visual Studio Code または GitHub Codespaces で Dev コンテナを使用します。
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 を使用する
次の 2 つのセクションでは、例: Azure Storage を作成で作成した Blob コンテナーにアクセスする 2 つの方法を説明します。
最初の方法 (認証を使用) では、サービス プリンシパルを使用したローカル開発時に Azure サービスに対する Python アプリの認証で説明されている DefaultAzureCredential
を使用してアプリを認証します。 この方法では最初に、アプリの ID に適切なアクセス許可を割り当てる必要があります。これが、推奨されるプラクティスです。
2 つ目の方法 (接続文字列を使用) では、接続文字列を使用して、ストレージアカウントに直接アクセスします。 こちらの方法の方が一見シンプルに見えますが、大きな欠点が 2 つあります。
接続文字列は本質的に、接続元のエージェントをストレージ "アカウント" に対して認証するものであり、そのアカウント内の個々のリソースに対して認証を行うものではありません。 そのため、接続文字列では、許可する承認の範囲が必要以上に広くなってしまう可能性があります。
接続文字列はアクセス情報をプレーン テキストで保持するため、適切に構築されていなかったり、セキュリティが適切に確保されていなかったりした場合に脆弱性のリスクが生じます。 そのような接続文字列が公開されれば、ストレージ アカウント内の広範なリソースへのアクセスに使用される可能性があります。
このような理由から、運用環境のコードでは認証方法を使用することをお勧めします。
4a: 認証付き Blob Storage を使用する
次のコードを含んだ 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": "00000000-0000-0000-0000-000000000000", "displayName": "{service-principal-name}", "password": "abcdefghijklmnopqrstuvwxyz", "tenant": "11111111-1111-1111-1111-111111111111" }
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 コンテナーからサービス プリンシパルへの Contributor アクセス許可を許可します。
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
引数は、対象となるロールの割り当て先を指定するものです。 この例では、[Storage Blob Data Contributor] ロールを、「blob-container-01」という名前のコンテナーのサービス プリンシパルに許可します。PythonAzureExample-Storage-rg
とpythonazurestorage12345
をお使いのストレージ アカウントとストレージ アカウントの正確な名前を含むリソース グループに置き換えます。 また、必要に応じて、BLOB コンテナーの名前を調整します。 間違った名前を使用すると、"Can not perform requested operation on nested resource. Parent resource 'pythonazurestorage12345' not found." (ネストされたリソースに対して要求された操作を実行できません。親リソース 'pythonazurestorage12345' が見つかりません) というエラーが表示されます。<AZURE_SUBSCRIPTION_ID> プレース ホルダーをお使いの Azure サブスクリプション ID に置き換えます。 (az account show を実行する、出力の
id
プロパティからお使いのサブスクリプション ID を取得できます。)
ヒント
bash シェルを使用した際に、ロール割り当てコマンドが「接続アダプターが見つかりません」というエラーを返す場合、
export MSYS_NO_PATHCONV=1
を設定して、パス変換を回避します。 詳しくは、こちらの issue を参照してください。アクセス許可が反映されるまで 1、2 分待機した後、コードをもう一度実行して、今度は動作することを確認します。 アクセス許可のエラーが再度表示された場合は、もう少し待ってから、もう一度コードを試してください。
ロールの割り当てについて詳しくは、Azure CLI を使用してロールのアクセス許可を割り当てる方法に関するページを参照してください。
4b: 接続文字列付き BLOB ストレージを使用する
次のコードを使用して、use_blob_conn_string.py という名前の Python ファイルを作成します。 ステップは、コメントで説明しています。
import os import uuid # Import the client object from the SDK library from azure.storage.blob import BlobClient # Retrieve the connection string from an environment variable. Note that a # connection string grants all permissions to the caller, making it less # secure than obtaining a BlobClient object using credentials. conn_string = os.environ["AZURE_STORAGE_CONNECTION_STRING"] # Create the client object for the resource identified by the connection # string, indicating also the blob container and the name of the specific # blob we want. blob_client = BlobClient.from_connection_string( conn_string, container_name="blob-container-01", blob_name=f"sample-blob-{str(uuid.uuid4())[0:5]}.txt", ) # 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_CONNECTION_STRING
という名前の環境変数を作成します。この値は、ストレージ アカウントの完全な接続文字列です。 (この環境変数は、さまざまな Azure CLI コメントでも使用されます)。az storage account show-connection-string コマンドを実行すると、ストレージ アカウントの接続文字列を取得できます。az storage account show-connection-string --resource-group PythonAzureExample-Storage-rg --name pythonazurestorage12345
PythonAzureExample-Storage-rg
とpythonazurestorage12345
をお使いのストレージ アカウントとストレージ アカウントの正確な名前を含むリソース グループに置き換えます。環境変数を設定するときは、引用符を含む出力内の
connectionString
プロパティの値全体を使用します。コードを実行します。
python use_blob_conn_string.py
既に述べたように、この方法はシンプルではありますが、接続文字列によって、ストレージ アカウント内のすべての操作が承認されます。 前のセクションで説明したように、運用環境のコードでは、具体的なアクセス許可を使用することをお勧めします。
5. BLOB の作成を確認する
どちらかの方法のコードを実行したら、[Azure Portal] にアクセスし、Blob コンテナーに移動して、sample-source.txt ファイルと同じ内容の sample-blob-{random}.txt という名前の新しい Blob が既存しているかを確認します。
AZURE_STORAGE_CONNECTION_STRING
という名前の環境変数を作成した場合は、Azure CLI を使用して、az storage blob list を使用した Blob が既存するかを確認できます。
az storage blob list --container-name blob-container-01
認証付き Blob ストレージを使用する手順に従った場合、ストレージ アカウントの接続文字列を使用して、--connection-string
パラメーターを前のコマンドに追加できます。 接続文字列を取得する方法については、「4b: 接続文字列で BLOB ストレージを使用する」の手順を参照してください。 引用符を含む接続文字列全体を使用します。
6: リソースをクリーンアップする
この例で使用したリソース グループおよびストレージ リソースを保持する必要が無い場合は、az group delete コマンドを実行します。 リソース グループではサブスクリプションに継続的な料金は発生しませんが、リソース グループ内のストレージ アカウントなどのリソースには料金が発生する可能性があります。 アクティブに使用していないグループをクリーン アップすることをお勧めします。 --no-wait
引数を使用すると、操作が完了するまで待機するのではなく、直ちにコマンドから戻ることができます。
az group delete -n PythonAzureExample-Storage-rg --no-wait
コードから ResourceManagementClient.resource_groups.begin_delete
メソッドを使用してリソース グループを削除することもできます。 「例: リソース グループを作成する」のコードでは、使用方法を示しています。
認証付き Blob ストレージを使用する手順に従った場合、作成したアプリケーション サービス プリンシパルを削除することが推奨されます。 az ad app delete コマンドを使用できます。 <AZURE_CLIENT_ID> プレースホルダーをサービス プリンシパルのアプリ ID で置き換えます。
az ad app delete --id <AZURE_CLIENT_ID>