Cloud Run functions を使用してイベント トリガーで Cloud Run を拡張する
Cloud Run functions を使用してコードをデプロイすることで、Cloud Run データベースの変更によってトリガーされるイベントを処理できます。これにより、独自のサーバーを実行しなくても、サーバー側の機能を追加できます。
このガイドでは、Firestore イベントから Cloud Run 関数のトリガーを作成する方法について説明します。
Firestore データベース内のイベントから Cloud Run functions をトリガーできます。トリガーされると、関数は Firestore API とクライアント ライブラリを介して、これらのイベントに応答して Firestore データベースを読み取り、更新します。
Firestore イベントが Cloud Run functions をトリガーするプロセスは、次の手順で構成されます。
サービスは、特定のドキュメントに変更が加えられるのを待ちます。
変更が発生すると、サービスがトリガーされ、タスクを実行します。
サービスは、影響を受けるドキュメントのスナップショットを含むデータ オブジェクトを受信します。
write
またはupdate
イベントの場合、トリガー イベントの前後のドキュメントの状態を表すスナップショットがデータ オブジェクトに含まれます。
始める前に
- 設定ページの説明に従って、Cloud Run に新しいプロジェクトを設定したことを確認してください。
Artifact Registry、Cloud Build、Cloud Run Admin API、Eventarc、Firestore Cloud Logging、Pub/Sub API を有効にします。
必要なロール
ユーザーまたは管理者が、デプロイ担当者アカウントとトリガー ID を付与する必要があります。必要に応じて、Pub/Sub サービス エージェントに次の IAM ロールを付与します。
デプロイ担当者のアカウントに必要なロール
Firestore イベントからトリガーするために必要な権限を取得するには、プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。
-
Cloud Build 編集者(
roles/cloudbuild.builds.editor
) -
Cloud Run 管理者(
roles/run.admin
) -
Datastore オーナー (
roles/datastore.owner
) -
Eventarc 管理者(
roles/eventarc.admin
) -
ログ表示アクセス者(
roles/logging.viewAccessor
) -
プロジェクト IAM 管理者(
roles/resourcemanager.projectIamAdmin
) -
サービス アカウント管理者(
roles/iam.serviceAccountAdmin
) -
サービス アカウント ユーザー(
roles/iam.serviceAccountUser
) -
Service Usage 管理者(
roles/serviceusage.serviceUsageAdmin
)
ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
デフォルトでは、Cloud Build の権限には、Artifact Registry アーティファクトをアップロードおよびダウンロードするための権限が含まれています。
トリガー ID に必要なロール
Compute Engine のデフォルトのサービス アカウントをメモしておいてください。テスト目的で、Eventarc トリガーに関連付けて、トリガーの ID を示すためです。このサービス アカウントは、Compute Engine を使用する Google Cloud サービスを有効にするか使用すると自動的に作成されます。メールアドレスの形式は次のとおりです。
PROJECT_NUMBER-compute@developer.gserviceaccount.com
PROJECT_NUMBER
は、使用する Google Cloudプロジェクト番号に置き換えます。プロジェクト番号は、 Google Cloud コンソールの [ようこそ] ページで確認できます。また、次のコマンドでも確認できます。gcloud projects describe PROJECT_ID --format='value(projectNumber)'
本番環境では、新しいサービス アカウントを作成して、必要最小限の権限を含む、最小権限の原則に従った 1 つ以上の IAM ロールを付与することを強くおすすめします。
- デフォルトでは、Cloud Run サービスを呼び出すことができるのは、プロジェクト オーナー、プロジェクト編集者、Cloud Run 管理者、起動元のみです。サービスごとにアクセスを制御できます。ただし、テスト目的の場合は、 Google Cloud プロジェクトの Cloud Run 起動元ロール(
run.invoker
)を Compute Engine サービス アカウントに付与してください。これにより、プロジェクト内のすべての Cloud Run サービスとジョブにロールが付与されます。gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role=roles/run.invoker
Cloud Run 起動元ロールを付与せずに認証済みの Cloud Run サービスのトリガーを作成すると、トリガーは正常に作成され、アクティブになります。ただし、トリガーが期待どおりに機能せず、次のようなメッセージがログに記録されます。
The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header.
- プロジェクトの Eventarc イベント レシーバーのロール(
roles/eventarc.eventReceiver
)を Compute Engine のデフォルト サービス アカウントに付与して、Eventarc トリガーがイベント プロバイダからイベントを受信できるようにします。gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role=roles/eventarc.eventReceiver
Pub/Sub サービス エージェントのオプションのロール
- 2021 年 4 月 8 日以前に、認証済みの Pub/Sub push リクエストをサポートするために Cloud Pub/Sub サービス エージェントを有効にした場合は、サービス アカウント トークン作成者のロール(
roles/iam.serviceAccountTokenCreator
)をサービス エージェントに付与します。それ以外の場合、このロールはデフォルトで付与されます。gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role=roles/iam.serviceAccountTokenCreator
Firestore データベースを設定する
サービスをデプロイする前に、Firestore データベースを作成する必要があります。
Firestore ページに移動します。
[Firestore データベースを作成] を選択します。
[データベースに名前を付ける] フィールドに、データベース ID(
firestore-db
など)を入力します。[構成オプション] セクションで、該当するセキュリティ ルールとともに [Firestore ネイティブ] がデフォルトで選択されています。
[ロケーション タイプ] で [リージョン] を選択し、データベースを配置するリージョンを選択します。この選択は永続的に適用されます。
[データベースを作成] をクリックします。
Firestore データモデルは、ドキュメントを含むコレクションで構成されます。ドキュメントには、一連の Key-Value ペアが含まれています。
Firestore でトリガーされる関数を作成する
Firestore イベントに応答する関数を作成するには、デプロイ中に次の内容を指定する準備を行います。
イベントタイプ
Firestore は、create
、update
、delete
、write
イベントをサポートしています。write
イベントには、ドキュメントに対するすべての変更が含まれます。
イベントタイプ | トリガー |
---|---|
google.cloud.firestore.document.v1.created (デフォルト) |
ドキュメントが最初に書き込まれたときにトリガーされます。 |
google.cloud.firestore.document.v1.updated |
すでに存在するドキュメントの値が変更されたときにトリガーされます。 |
google.cloud.firestore.document.v1.deleted |
データを含むドキュメントが削除されたときにトリガーされます。 |
google.cloud.firestore.document.v1.written |
ドキュメントが作成、更新、削除されたときにトリガーされます。 |
google.cloud.firestore.document.v1.created.withAuthContext |
created と同じですが、認証情報を追加します。 |
google.cloud.firestore.document.v1.updated.withAuthContext |
updated と同じですが、認証情報を追加します。 |
google.cloud.firestore.document.v1.deleted.withAuthContext |
deleted と同じですが、認証情報を追加します。 |
google.cloud.firestore.document.v1.written.withAuthContext |
written と同じですが、認証情報を追加します。 |
ワイルドカードは、トリガー内で中括弧を使用して記述します。例: projects/YOUR_PROJECT_ID/databases/(default)/documents/collection/{document_wildcard}
トリガー イベント フィルタ
サービスをトリガーするには、リッスンするドキュメント パスを指定します。ドキュメント パスは、サービスと同じ Google Cloud プロジェクトに存在する必要があります。
有効なドキュメント パスの例を次に示します。
users/marie
: 1 つのドキュメント(/users/marie
)をモニタリングします。users/{username}
: すべてのユーザー ドキュメントをモニタリングします。コレクション内のすべてのドキュメントをモニタリングする場合は、ワイルドカードを使用します。users/{username}/addresses/home
: すべてのユーザーの自宅住所のドキュメントをモニタリングします。users/{username}/addresses/{addressId}
: すべての住所ドキュメントをモニタリングします。users/{user=**}
: すべてのユーザー ドキュメントと、各ユーザー ドキュメントのサブコレクション(/users/userID/address/home
や/users/userID/phone/work
など)内のドキュメントをモニタリングします。users/{username}/addresses
: 無効なアドレスパス。ドキュメントではなく、サブコレクションaddresses
を参照します。
ワイルドカードとパラメータ
モニタリングするドキュメントが不明な場合は、ドキュメント ID の代わりに {wildcard}
を使用します。
users/{username}
は、すべてのユーザー ドキュメントに対する変更をリッスンします。
この例では、users
にあるドキュメントの任意のフィールドが変更されると、{username}
というワイルドカードと照合されます。
users
に含まれるドキュメントにサブコレクションがある場合、サブコレクションのいずれかに含まれるドキュメントのフィールドが変更されても、{username}
ワイルドカードはトリガーされません。サブコレクション内のイベントにも応答することが目標なら、マルチセグメント ワイルドカード {username=**}
を使用します。
ワイルドカードに一致した部分が、ドキュメント パスから抽出されます。明示的なコレクションまたはドキュメント ID に置き換えるワイルドカードは、必要な数だけ定義できます。マルチセグメント ワイルドカード({username=**}
など)は 1 つまで使用できます。
関数コード
ネイティブ モードの Firestore イベントを使用して Cloud Run 関数をトリガーする方法については、例をご覧ください。
proto 依存関係をソースに含める
関数のソース ディレクトリに Cloud Run data.proto
ファイルを含める必要があります。このファイルは、ソース ディレクトリにも含める必要がある次の proto をインポートします。
依存関係に同じディレクトリ構造を使用します。たとえば、struct.proto
は google/protobuf
内に配置します。
これらのファイルは、イベントデータをデコードするのに必要です。関数のソースにこれらのファイルが含まれていない場合は、実行時にエラーが返されます。
イベント属性
各イベントには、イベントがトリガーされた時間など、イベントに関する情報を含むデータ属性が含まれます。Cloud Run は、イベントに関連するデータベースとドキュメントに関するデータを追加します。これらの属性には、次のようにアクセスできます。
Java
logger.info("Function triggered by event on: " + event.getSource()); logger.info("Event type: " + event.getType()); logger.info("Event time " + event.getTime()); logger.info("Event project: " + event.getExtension("project")); logger.info("Event location: " + event.getExtension("location")); logger.info("Database name: " + event.getExtension("database")); logger.info("Database document: " + event.getExtension("document")); // For withAuthContext events logger.info("Auth information: " + event.getExtension("authid")); logger.info("Auth information: " + event.getExtension("authtype"));
Node.js
console.log(`Function triggered by event on: ${cloudEvent.source}`); console.log(`Event type: ${cloudEvent.type}`); console.log(`Event time: ${cloudEvent.time}`); console.log(`Event project: ${cloudEvent.project}`); console.log(`Event location: ${cloudEvent.location}`); console.log(`Database name: ${cloudEvent.database}`); console.log(`Document name: ${cloudEvent.document}`); // For withAuthContext events console.log(`Auth information: ${cloudEvent.authid}`); console.log(`Auth information: ${cloudEvent.authtype}`);
Python
print(f"Function triggered by change to: {cloud_event['source']}") print(f"Event type: {cloud_event['type']}") print(f"Event time: {cloud_event['time']}") print(f"Event project: {cloud_event['project']}") print(f"Location: {cloud_event['location']}") print(f"Database name: {cloud_event['database']}") print(f"Document: {cloud_event['document']}") // For withAuthContext events print(f"Auth information: {cloud_event['authid']}") print(f"Auth information: {cloud_event['authtype']}")
イベントの構造
このトリガーは、次のようなイベントでサービスを呼び出します。
{ "oldValue": { // Update and Delete operations only A Document object containing a pre-operation document snapshot }, "updateMask": { // Update operations only A DocumentMask object that lists changed fields. }, "value": { // A Document object containing a post-operation document snapshot } }
それぞれの Document
オブジェクトに 1 つまたは複数の Value
オブジェクトが含まれます。型の詳細については、Value
ドキュメントをご覧ください。
関数のトリガーを作成する
タブをクリックして、使用するツールでの手順を確認してください。
コンソール
Google Cloud コンソールを使用して関数を作成する場合、関数の作成時にトリガーを追加することもできます。関数のトリガーを作成する手順は次のとおりです。
Google Cloud コンソールで Cloud Run に移動します。
[関数を作成] をクリックし、関数の詳細を入力します。デプロイ時に関数を構成する方法については、関数をデプロイするをご覧ください。
[トリガー] セクションで [トリガーを追加] をクリックします。
[Firestore トリガー] を選択します。
[Eventarc トリガー] ペインで、トリガーの詳細を次のように変更します。
[トリガー名] フィールドにトリガーの名前を入力するか、デフォルトの名前を使用します。
リストからトリガーのタイプを選択します。
Google のソース: Pub/Sub、Cloud Storage、Firestore などの Google イベント プロバイダのトリガーを指定できます。
サードパーティ: Eventarc ソースを提供する Google 以外のプロバイダと統合できます。詳細については、Eventarc のサードパーティ イベントをご覧ください。
[イベント プロバイダ] リストから [Firestore] を選択し、関数をトリガーするイベントの種類を提供するプロダクトを選択します。イベント プロバイダのリストについては、イベント プロバイダと宛先をご覧ください。
[イベントの種類] リストから [type=google.cloud.firestore.document.v1.created] を選択します。トリガーの構成は、サポートされているイベントタイプによって異なります。詳細については、イベントタイプをご覧ください。
[フィルタ] セクションで、データベース、オペレーション、属性の値を選択するか、デフォルト値を使用します。
[リージョン] フィールドが有効になっている場合は、Eventarc トリガーのロケーションを選択します。一般に、Eventarc トリガーのロケーションは、イベントをモニタリングする Google Cloud リソースのロケーションと一致している必要があります。ほとんどの場合に、関数を同じリージョンにデプロイすることも必要です。Eventarc トリガーのロケーションの詳細については、Eventarc のロケーションについてをご覧ください。
[サービス アカウント] フィールドで、サービス アカウントを選択します。Eventarc トリガーはサービス アカウントにリンクされ、関数を呼び出すときに ID として使用します。Eventarc トリガーのサービス アカウントには、関数を呼び出す権限が必要です。デフォルトでは、Cloud Run は Compute Engine のデフォルトのサービス アカウントを使用します。
受信リクエストの送信先であるサービスの URL パスを指定することもできます。これは、トリガーのイベントの送信先である宛先サービスの相対パスです。例:
/
、/route
、route
、route/subroute
.
必須フィールドに値を入力したら、[トリガーを保存] をクリックします。
gcloud
gcloud CLI を使用して関数を作成する場合は、まず関数をデプロイしてからトリガーを作成する必要があります。関数のトリガーを作成する手順は次のとおりです。
サンプルコードのあるディレクトリで次のコマンドを実行して、関数をデプロイします。
gcloud run deploy FUNCTION \ --source . \ --function FUNCTION_ENTRYPOINT \ --base-image BASE_IMAGE_ID \ --region REGION
次のように置き換えます。
FUNCTION: デプロイする関数の名前。このパラメータは省略できますが、省略すると名前の入力を求められます。
FUNCTION_ENTRYPOINT: ソースコード内の関数のエントリ ポイント。これは、関数の実行時に Cloud Run が実行するコードです。このフラグには、ソースコード内に存在する関数名または完全修飾クラス名を指定する必要があります。
BASE_IMAGE_ID: 関数のベースイメージ環境。ベースイメージと各イメージに含まれるパッケージの詳細については、ランタイム ベースイメージをご覧ください。
REGION: 関数をデプロイする Google Cloudリージョン。例:
europe-west1
。
次のコマンドを実行して、イベントをフィルタするトリガーを作成します。
gcloud eventarc triggers create TRIGGER_NAME \ --location=EVENTARC_TRIGGER_LOCATION \ --destination-run-service=FUNCTION \ --destination-run-region=REGION \ --event-filters="type=google.cloud.firestore.document.v1.created" \ --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
次のように置き換えます。
TRIGGER_NAME は、トリガーの名前に置き換えます。
EVENTARC_TRIGGER_LOCATION は、Eventarc トリガーのロケーションに置き換えます。一般に、Eventarc トリガーのロケーションは、イベントをモニタリングする Google Cloud リソースのロケーションと一致している必要があります。ほとんどの場合に、関数を同じリージョンにデプロイすることも必要です。詳細については、Eventarc のロケーションをご覧ください。
FUNCTION: デプロイする関数の名前。
REGION: 関数の Cloud Run リージョン。
PROJECT_NUMBER: Google Cloud プロジェクト番号。Eventarc トリガーはサービス アカウントにリンクされ、関数を呼び出すときに ID として使用します。Eventarc トリガーのサービス アカウントには、関数を呼び出す権限が必要です。デフォルトでは、Cloud Run はデフォルトのコンピューティング サービス アカウントを使用します。
各
event-filters
フラグはイベントのタイプを指定します。関数は、イベントがevent-filters
フラグで指定されたすべての条件を満たす場合にのみトリガーされます。各トリガーには、Firestore に書き込まれた新しいドキュメントや Cloud Storage にアップロードされたファイルなど、サポートされているイベントタイプを指定するevent-filters
フラグが必要です。作成後にイベント フィルタのタイプを変更することはできません。イベント フィルタの種類を変更するには、新しいトリガーを作成して古いトリガーを削除する必要があります。(省略可)さらにフィルタを追加するには、--event-filters
フラグを繰り返し、サポートされているフィルタをATTRIBUTE=VALUE
の形式で指定します。
Terraform
Cloud Run 関数の Eventarc トリガーを作成するには、Terraform を使用してトリガーを作成するをご覧ください。
例
次の例では、Firestore ネイティブ モードのイベントを使用して Cloud Run 関数をトリガーする方法について説明します。
例 1: Hello Firestore 関数
次のサンプルは、トリガーされた Firestore イベントのフィールドを出力します。
Node.js
Python
Go
Java
C#
関数をデプロイする
Hello Firestore
関数をデプロイするには、次のコマンドを実行します。
Firestore データベースをまだ設定していない場合は、設定します。
関数をデプロイするには、関数のトリガーを作成するをご覧ください。
関数をテストする
Hello Firestore
関数をテストするには、Firestore データベースに users
というコレクションを設定します。
Google Cloud コンソールで、[Firestore データベース] ページに移動します。
[コレクションを開始] をクリックします。
コレクション ID として
users
を指定します。コレクションの最初のドキュメントの追加を開始するには、[最初のドキュメントの追加] で、自動生成されたドキュメント ID を使用します。
ドキュメントに少なくとも 1 つのフィールドを追加し、名前と値を指定します。たとえば、[フィールド名] に「
username
」、[フィールド値] に「rowan
」と入力します。完了したら [保存] をクリックします。
この操作により新しいドキュメントが作成され、関数がトリガーされます。
関数がトリガーされたことを確認するには、 Google Cloud コンソールの Cloud Run の概要ページで関数のリンク名をクリックして、[サービスの詳細] ページを開きます。
[ログ] タブを選択して、次の文字列を探します。
Function triggered by change to: //firestore.googleapis.com/projects/your-project-id/databases/(default)'
例 2: Convert to Uppercase 関数
次の例では、ユーザーが追加した値を取得し、その場所にある文字列を大文字に変換して、値を大文字の文字列に置き換えています。
Node.js
protobufjs を使用して、イベントデータをデコードします。ソースに google.events.cloud.firestore.v1
data.proto
を配置します。
Python
Go
Java
C#
関数をデプロイする
Convert to Uppercase
関数をデプロイするには、次のコマンドを実行します。
Firestore データベースをまだ設定していない場合は、設定します。
関数をデプロイするには、関数のトリガーを作成するをご覧ください。
関数をテストする
デプロイした Convert to Uppercase
関数をテストするには、Firestore データベースに messages
というコレクションを設定します。
Google Cloud コンソールで、[Firestore データベース] ページに移動します。
[コレクションを開始] をクリックします。
コレクション ID として
messages
を指定します。コレクションの最初のドキュメントの追加を開始するには、[最初のドキュメントの追加] で、自動生成されたドキュメント ID を使用します。
デプロイされた関数をトリガーするには、フィールド名が
original
で、フィールド値がminka
のドキュメントを追加します。ドキュメントを保存すると、値フィールドの小文字の単語が大文字に変換されます。
その後、フィールド値を編集して小文字を含めると、関数が再度トリガーされ、すべての小文字が大文字に変換されます。
関数の制限事項
- 順序は保証されません。短時間に複数の変更を行うと、予期しない順序で関数の呼び出しがトリガーされることがあります。
- イベントは必ず 1 回以上処理されますが、1 つのイベントで関数が複数回呼び出される場合があります。「正確に 1 回」のメカニズムに依存することは避け、べき等になるように関数を記述してください。
- トリガーは、単一のデータベースに関連付けられます。複数のデータベースに一致するトリガーは作成できません。
- データベースを削除しても、そのデータベースのトリガーは自動的に削除されません。トリガーはイベントの配信を停止しますが、トリガーを削除するまで存在し続けます。