📝

Azure FunctionsからマネージドID認証でBlobへ疎通をする

2025/03/10に公開

執筆日

2025/3/10

やりたいこと

Azure FunctionsからマネージドID認証でBlobへ疎通を行いたい。
構成は以下。

前提

  • 構成図通りにAzure環境が準備されていること

手順

  1. Azure FunctionsにBlob共同作成者,AcrPullを付与する
  2. Azure Blob Storageのコンテナを作成し、適当にファイルをUploadする
  3. 以下を参考にDockerベースのFunctionsをLocalで構築する

https://zenn.dev/headwaters/articles/746a73656cfbbe

  1. functions_app.pyを以下に書き変える
code
function_app.py
import json
import azure.functions as func  
import logging  
from azure.identity import DefaultAzureCredential  
from azure.storage.blob import BlobServiceClient  
  
# Blob Storage の接続情報  
BLOB_STORAGE_ACCOUNT_URL = <"https://<blob名>.blob.core.windows.net/">
CONTAINER_NAME = <"コンテナ名">  
credential = DefaultAzureCredential()  
blob_service_client = BlobServiceClient(account_url=BLOB_STORAGE_ACCOUNT_URL, credential=credential)  
container_client = blob_service_client.get_container_client(CONTAINER_NAME)  
  
app = func.FunctionApp()  
  
@app.route(route=<"関数名">, auth_level=func.AuthLevel.FUNCTION)  
def test(req: func.HttpRequest) -> func.HttpResponse:  
    logging.info("HTTP trigger function processed a request.")  
    try:  
        blob_list = container_client.list_blobs()   
        blobs = [blob.name for blob in blob_list]  
        return func.HttpResponse(  
            json.dumps({"blobs": blobs}),  
            status_code=200,  
            mimetype="application/json"  
        )  
  
    except Exception as e:  
        logging.error(f"An error occurred: {e}")  
        return func.HttpResponse(  
            "An error occurred while accessing Blob Storage.",  
            status_code=500  
        )

認証周りは、DefaultAzureCredentialを使う。

from azure.identity import DefaultAzureCredential
# Blob Storage の接続情報  
BLOB_STORAGE_ACCOUNT_URL = <"https://<blob名>.blob.core.windows.net/">
CONTAINER_NAME = <"コンテナ名">  
credential = DefaultAzureCredential()  
blob_service_client = BlobServiceClient(account_url=BLOB_STORAGE_ACCOUNT_URL, credential=credential)
  1. Azure portalからテストを実行し、Blobの中身が確認できることを確認する

Localでテストする場合はどうすればよい?

ふと、疑問に出ました。
ただ、LocalからBlobへのアクセスは出来なくない?
やってみる、やはりできない。

ManagedIdentityCredential.get_token failed: ManagedIdentityCredential authentication unavailable, no managed identity endpoint found.    
[2025-02-09T05:06:46.475Z] ImdsCredential.get_token failed: ManagedIdentityCredential authentication unavailable, no managed identity endpoint found.

なぜか?

以下の記事にあるように認証には順番がある。

環境変数で定義されているように環境変数 AZURE_CLIENT_ID、AZURE_CLIENT_SECRET、および AZURE_TENANT_ID を設定することで、それらの値によって指定されたサービス プリンシパルとして認証するように DefaultAzureCredential が構成されます。
ビルダーまたは環境変数AZURE_CLIENT_IDの設定.managedIdentityClientId(String)は、ユーザー割り当てマネージド ID として認証するように構成DefaultAzureCredentialしますが、空のままにすると、システム割り当てマネージド ID として認証するように構成されます。
ビルダーまたは環境変数AZURE_TENANT_IDの設定.tenantId(String)は、共有トークン キャッシュまたは IntelliJ IDEA のいずれかの特定のテナントに対して認証するように構成DefaultAzureCredentialします。
環境変数 AZURE_USERNAME を設定すると、DefaultAzureCredential は、共有トークンキャッシュから対応するキャッシュされたトークンを選択するように構成されます。

順序 認証方式
1 環境変数
2 マネージド ID
3 IntelliJ アカウント
4 Visual Studio Code
5 Azure CLI

https://learn.microsoft.com/ja-jp/azure/developer/java/sdk/authentication/azure-hosted-apps#defaultazurecredential

なので

Localでテストをする際には、AZURE_CLIENT_ID,AZURE_CLIENT_SECRET,AZURE_TENANT_IDを環境変数に設定する

変数名
AZURE_CLIENT_ID Azure AD アプリケーション ID
AZURE_CLIENT_SECRET Azure AD アプリケーションに設定されたクライアントシークレット
AZURE_TENANT_ID Azure AD テナント ID
ヘッドウォータース

Discussion