🍚

VSCodeを利用してAzure FunctionsをCosmosDBに接続

2024/10/19に公開

概要

こちらの記事で作成したAzureのFunctionsの続きとして、このFunctionsからCosmos DBに接続する方法について下記チュートリアルをもとに実行したのでその内容について個人の備忘録としてまとめていきます(写経)。

https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-add-output-binding-cosmos-db-vs-code?pivots=programming-language-python

環境セットアップ

前回の記事の環境構築の内容に加えて、下記の拡張機能をVSCodeにインストールします。

https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-cosmosdb

Azure Cosmos DBアカウントを選択する

Azure Cosmos DBアカウントをサーバーレスアカウントの種類として作成します。この使用量ベースのモードにより、Azure Cosmos DB がサーバーレス ワークロードのための強力なオプションになります。

  1. Visual Studio Code で、[表示]>[コマンド パレット...] を選んでから、コマンド パレットで Azure Databases: Create Server... を検索します
  2. プロンプトで、次の情報を入力します。

新しいアカウントがプロビジョニングされると、通知領域にメッセージが表示されます。
ex)

Azure Cosmos DB データベースとコンテナーを作成する

  1. VSCodeのactivityバーでAzure アイコンを選び、[リソース]>[Azure Cosmos DB] を展開し、アカウントを右クリックして、[データベースの作成...] を選びます。

  1. プロンプトで、次の情報を入力します。

  2. [OK] を選択してコンテナーとデータベースを作成します。

関数アプリの設定を更新する

前回作成したFunctionsを更新して作成したCosmos DBにJSONドキュメントを書き込むように設定します。Cosmos DBアカウントに接続するにはその接続文字列をアプリの設定に追加する必要があります。その後、新しい設定をlocal.settings.jsonファイルにダウンロードして、ローカルで実行する際にAzure Cosmos DBアカウントに接続できるようにします。

  1. Visual Studio Code で、新しい Azure Cosmos DB アカウントを右クリックし、[Copy Connection String] (接続文字列のコピー) を選びます。

  1. F1 キーを押してコマンド パレットを開き、コマンド Azure Functions: Add New Setting... を検索して実行します。
  2. 前の記事で作成した関数アプリを選択します。 プロンプトで、次の情報を入力します。

これにより、Azure の関数アプリ内に 接続 CosmosDbConnectionSettingという名前のアプリケーション設定が作成されます。 これで、この設定をローカルの設定の json ファイルにダウンロードできます。

  1. F1キーをもう一度押してコマンド パレットを開き、コマンド Azure Functions: Download Remote Settings... を検索して実行します。
  2. 前の記事で作成した関数アプリを選択します。 Yes to allを選択して既存のローカル設定を上書きします。

これにより、新しい接続文字列の設定を含む、すべての設定が Azure からローカルプロジェクトにダウンロードされます。 ダウンロードした設定のほとんどは、ローカルでの実行時には使用されません。

バインディング拡張機能を登録する

Azure Cosmos DB の出力バインドを使用しているため、このプロジェクトを実行する前に対応するバインド拡張機能をインストールしておく必要があります。

プロジェクトは、拡張機能バンドルを使用するように構成されています。これにより、事前定義された一連の拡張機能パッケージが自動的にインストールされます。

拡張機能バンドルの使用は、プロジェクトのルートにある host.json ファイルで※次のように有効になっています。

host.json
{
  "version": "2.0",
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[3.*, 4.0.0)"
  } 
}

※versionや設定によってloggingなど他の設定が追加されている場合もあります。

出力バインディングを追加する

次のコードに一致するようにfunction_app.pyを更新します。関数の定義にoutputDocumentパラメーターを追加し、if name:ステートメントの下にoutputDocument.set()を追加します。

function_app.py
import azure.functions as func
import logging

app = func.FunctionApp()

@app.function_name(name="HttpTrigger1")
@app.route(route="hello", auth_level=func.AuthLevel.ANONYMOUS)
@app.queue_output(arg_name="msg", queue_name="outqueue", connection="AzureWebJobsStorage")
@app.cosmos_db_output(arg_name="outputDocument", database_name="my-database", container_name="my-container", connection="CosmosDbConnectionSetting")
def test_function(req: func.HttpRequest, msg: func.Out[func.QueueMessage],
    outputDocument: func.Out[func.Document]) -> func.HttpResponse:
     logging.info('Python HTTP trigger function processed a request.')
     logging.info('Python Cosmos DB trigger function processed a request.')
     name = req.params.get('name')
     if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

     if name:
        outputDocument.set(func.Document.from_dict({"id": name}))
        msg.set(name)
        return func.HttpResponse(f"Hello {name}!")
     else:
        return func.HttpResponse(
                    "Please pass a name on the query string or in the request body",
                    status_code=400
                )

ドキュメント {"id": "name"}は、バインドで指定されたデータベースコレクション内に作成されます。

関数をローカルで実行する

  1. 前の記事と同様、F5 キーを押して関数アプリ プロジェクトと Core Tools を起動します。
  2. Core Tools を実行したまま、Azure: Functions 領域に移動します。 [Functions] の [ローカル プロジェクト]>[Functions] を展開します。 HttpExample 関数を右クリック (Mac では Ctrl キーを押しながらクリック) し、 Execute Function Now を選択します。

  1. [Enter request body](要求本文を入力してください) に、要求メッセージ本文の値として { "name": "Azure" } が表示されます。 Enter キーを押して、この要求メッセージを関数に送信します。

正常通りに実行されると下記のようなレスポンスが返ってきます。

Executed function "HttpTrigger1". Response: "Hello Azure!"
  1. 応答が返されたら、Ctrl + C キーを押して Core Tools を停止します。

JSON ドキュメントが作成されたことを確認する

  1. Azure portal で Azure Cosmos DB アカウントに戻り、 [データ エクスプローラー] を選択します。
  2. データベースとコンテナーを展開し、 [項目] を選択して、コンテナー内に作成されたドキュメントを一覧表示します。
  3. 出力バインドによって新しい JSON ドキュメントが作成されたことを確認します。

更新したアプリを再デプロイして検証する

  1. Visual Studio Code で、F1 キーを押してコマンド パレットを開きます。 コマンド パレットで、Azure Functions: Deploy to function app... を検索して選択します。
  2. 最初の記事で作成した関数アプリを選択します。 同じアプリにプロジェクトを再デプロイしているため、 [デプロイ] を選択して、ファイルの上書きに関する警告を無視します。
  3. デプロイの完了後、もう一度 Execute Function Now 機能を使用して Azure で関数をトリガーできます。

実行すると次のような通知がVSCode上で確認できます

Executed function "HttpTrigger1". Response: "Hello Tomato!"

また、次のようなcurlでも実行を確認できます。

リクエストパラメータを指定した場合
% curl "https://${FUNC_URL}.azurewebsites.net/api/hello" \
    -H "Content-Type: application/json" \
    -d '{"name": "Apple"}'
Hello Apple!
リクエストパラメータが未指定の場合
% curl "https://${FUNC_URL}.azurewebsites.net/api/hello" \
    -H "Content-Type: application/json" 
Please pass a name on the query string or in the request body
  1. この場合もAzure Cosmos DB コンテナーに作成されたドキュメントを確認し、出力バインドによって再び新しいJSONドキュメントが生成されていることを確認します。

デプロイしたリソースのクリーンアップ

https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-add-output-binding-cosmos-db-vs-code?pivots=programming-language-python#clean-up-resources を参考に作成したリソースグループを選択して削除します。

まとめ

JSONドキュメントがAzure Cosmos DBコンテナーに書き込むようなHTTP によってトリガーされる関数を作成しました。
FunctionsやCosmosを利用することで簡単にイベントドリブンな処理を実装できることを確認できました。出力バインディングについての内容を調べてみたりより実践的な使用方法について今後調べていきたいと思いました。

Discussion