Eventarc でサーバレスに非同期処理を実現しよう
この記事は Google Cloud Japan Customer Engineer Advent Calendar 2020 の 18日目の記事です。
みなさんこんにちは、最近すっかり寒くなってきましたね。来週はクリスマス、もうすぐ年越しで、イベント尽くしです。イベント… Event… ということで、今年の 10 月に Eventarc という機能がリリースされたのをご存知でしょうか(強引)?
Eventarc とは
GCS にファイルが置かれたり、Firestore に書き込みがあった場合など、Google Cloud 上でイベントがあった際に別の処理を実行させたい場合、Cloud Functions や Pub/Sub を利用する方法があります。それも良い方法なのですが、Pub/Sub が対応していないイベントなど、より多くのサービスを連携させたいケースもあるかと思います。
Eventarc を利用することで、Cloud 監査ログからイベントを受信して、マネージドの Cloud Run サービスを呼び出すことが出来ます。Cloud 監査ログはその名の通り、監査ログを保持する機能で、その特性を利用して現在 60 以上の Event Sources が設定可能となっており、Google Cloud の多くのサービスとイベント連携が実現出来ます。
また、Eventarc のフォーマットはソースに関係なく、すべてのイベントを CloudEvents 標準準拠とし、一貫したデベロッパー エクスペリエンスを開発者に提供します。
※ Eventarc の機能は、現在まだプレビューの点にご注意ください
このブログでは Eventarc の連携方法について説明した後、どのようなケースで利用出来そうか、いくつか例を考えてみたいと思います。
連携方法
連携手順は以下のようになります。
- Cloud Run サービスの作成
- 監査ログの有効化
- イベントのトリガー設定
1. Cloud Run サービスの作成
まず、イベント レシーバーとなる Cloud Run サービスの作成をします。フルマネージドの Cloud Run で、現在トリガーがサポートされているのは、以下 4 リージョンとなります。
asia-east1(台湾)
europe-west1(ベルギー)
us-central1(アイオワ)
us-east1(サウスカロライナ)
尚、このブログでは触れませんが、Cloud Run for Anthos を利用すると、GKE 上で Cloud Run を動かすような構成になり、 対応リージョンが GKE の範囲に広がるだけでなく、カスタム イベントの作成や、Kubernetes Service へのイベント送信など、設計の幅を広げることが可能です。
2. 監査ログの有効化
次に、イベントを連携するサービスの監査ログタイプを有効化する必要があります。Cloud コンソールのメニューで IAM と管理 > 監査ログ にアクセスし、必要な監査ログタイプを有効化します。
3. イベントのトリガー設定
最後に、Cloud Run のサービス詳細にある、トリガータブで、連携するイベントの詳細を設定します。
トリガーさせたいイベントを選択し、リソース、イベントの受信元、呼び出しの設定 3 項目を設定します。
リソース
Any resource か Specific resource(s) を選択します。Specific resource(s) で指定するリソース名の値は、下記のページが分かりやすいです。複数指定する場合は、カンマ区切りで指定します。
例:Cloud Storage イベントのトリガーで指定するリソース名バケット:projects/_/buckets/{バケット名}
オブジェクト:projects/_/buckets/{バケット名}/objects/{オブジェクト名}
Cloud Logging で以下のようなクエリを実行し、resourceName を参照すると、実際に出力されている値が確認出来ると思います。
[クエリ]
protoPayload.@type="type.googleapis.com/google.cloud.audit.AuditLog"
protoPayload.methodName="storage.objects.create"[出力例]
{
protoPayload: {
@type: "type.googleapis.com/google.cloud.audit.AuditLog"
...
resourceName: "projects/_/buckets/events-quickstart-xxxxx/objects/aaa.png"
...
}
...
}
イベントの受信元
単一リージョン(前述の 4 リージョンから選択)か、すべてのリージョンを選択します。すべてのリージョンを選択した場合、前述の 4 リージョンに限らないトリガーも含まれます。
例えば、東京リージョンや大阪リージョンで発生したイベントを、Cloud Run サービスが稼働する台湾リージョンに送信するといった流れになります。
呼び出しの設定
Cloud Run サービスを呼び出すサービスアカウントと、受信したイベントの送信先となる URL パスを指定します。サービス間認証を入れる場合は、サービスアカウントに Cloud Run Invoker ロールを付与する必要があります。
Eventarc を介したリクエストは、Cloud Run サービスの HTTPS エンドポイントへ、POST リクエストが送信されます。送信データについては下記のドキュメントを参照してください。このドキュメントは、Cloud Run for Anthos について書かれていますが、フルマネージドな Cloud Run を利用する場合も同様に、リクエストヘッダや本文にデータが含まれています。
参考までに、GCS にファイルを作成したイベントの、リクエスト ヘッダ情報をロギングすると、CloudEvents 準拠の ce- から始まるヘッダは以下のような出力となりました(一部 xxxxxxx で置換しています)。
ce-dataschema: "https://googleapis.github.io/google-cloudevents/jsonschema/google/events/cloud/audit/v1/LogEntryData.json"
ce-subject: "storage.googleapis.com/projects/_/buckets/events-quickstart-xxxxxxx/objects/aaa.png"
ce-type: "google.cloud.audit.log.v1.written"
ce-time: "2020-12-15T07:42:03.335659370Z"
ce-methodname: "storage.objects.create"
ce-servicename: "storage.googleapis.com"
ce-source: "//cloudaudit.googleapis.com/projects/xxxxxxx/logs/data_access"
ce-id: "projects/xxxxxxx/logs/cloudaudit.googleapis.com%2Fdata_access-qmny9rd8lmy1608018122780149"
ce-specversion: "1.0"
ce-resourcename: "projects/_/buckets/events-quickstart-xxxxxxx/objects/aaa.png"
ce-recordedtime: "2020-12-15T07:42:02.780149404Z"
(参考)gcloud CLI でトリガーを作成する
下記のように、gcloud CLI を利用してトリガーを作成することも可能です。
gcloud beta eventarc triggers create {トリガー名} \
--location={イベントの受信元リージョン} \
--destination-run-service={Cloud Run サービス名} \
--destination-run-path={Cloud Run サービス URL パス} \
--destination-run-region={Cloud Run サービスリージョン} \
--matching-criteria="type={イベントタイプ}" \
--matching-criteria="serviceName={サービス名}" \
--matching-criteria="methodName={メソッド名}" \
--matching-criteria="resourceName={リソース名}" \
--service-account={Cloud Run サービス呼び出しサービスアカウント}例:Cloud Storage イベントのトリガーを作成gcloud beta eventarc triggers create test-event-trigger \
--location=asia-east1 \
--destination-run-service=helloworld-events \
--destination-run-path=/ \
--destination-run-region=asia-east1 \
--matching-criteria="type=google.cloud.audit.log.v1.written" \
--matching-criteria="serviceName=storage.googleapis.com" \
--matching-criteria="methodName=storage.objects.create" \
--matching-criteria="resourceName=projects/_/buckets/events-sample-bucket/objects/aaa.png" \
--service-account=123456789012-compute@developer.gserviceaccount.com
このトリガーを活用して、ユースケースを考えてみたいと思います。
Cloud Storage 連携
連携方法の例にも挙げましたが、クイックスタートでも利用されているため、一番想像しやすい連携かと思います。
バケットに対しての get、list、create、delete 操作や、オブジェクトに対し get、list、create、update、delete 操作が行われたイベントをトリガーに出来ます。
注意点としては、オブジェクトパスの前方一致が効かないようで、特定バケット内の全てのオブジェクトを追跡したい場合は、これまで通り Cloud Pub/Sub や Cloud Functions を連携させた方が良さそうです。
多くのケースは上記によって連携出来ますが、Eventarc でしか対応していない get 操作を活用できないか考えてみます。
バケット毎に、オブジェクトのライフサイクルを定義できますが、Standard Storage から保存が低コストなストレージクラスに変更すると、データのオペレーションや取得にも費用がかかるようになります。最小保存期間の制限はありますが、それを超えてアクセスが続いているようであれば、ストレージクラスを戻すことも考えた方が良いでしょう。
これに対して、Eventarc のトリガーを設定することで、固定パスのオブジェクトのアクセスを検知するようにし、最適なストレージクラスに戻すような処理が Cloud Run で実行可能となります。
Cloud Pub/Sub 連携
Cloud Pub/Sub は Eventarc が発表される前から、トピックに送信されたメッセージを Cloud Run へ送信する連携が可能でした。監査ログの追加によって、連携できるトリガー(トピック作成イベントなど)が増えていますが、元々あったメッセージの連携については、別のタイプとして選択するようになっています。
Google Cloud では、Cloud Pub/Sub を中継してプロダクト間連携を実現する方法が多く存在しています。いくつか例を上げると、
- Cloud Storage にファイルが置かれたら、イベントを Pub/Sub へ送信
- Cloud Logging で、作成した個別のフィルタに基づいて、Pub/Sub トピックにログイベントを送信
などです。アプリケーション実装で、非同期処理を行う際に Pub/Sub が直接利用されることも多いです。後続処理を Cloud Run で実行させていくような多くのユースケースが考えられます。
Cloud IAM 連携
Cloud IAM の、サービスアカウント関連イベントや、Cloud Resource Manager の IAM ポリシー設定イベントが、トリガーとして選択可能です。
[イベントタイプ]
Cloud IAM > google.iam.admin.v1.CreateServiceAccount
Cloud Resource Manager > SetIamPolicy
Cloud IAM の影響はサービスに関わらず非常に大きいため、編集可能なメンバーを制限しているかと思いますが、何か変更があった場合は検知しておきたいところです。
サービスアカウントの作成や削除、IAM ポリシーの変更を、監査ログから検知して管理者へ通知するだけでなく、Eventarc によって、複雑な後続タスクを Cloud Run で実行するなど、対応範囲を柔軟に広げることができます。
最後に
Eventarc によって、より多くのプロダクト間連携が実現できます。利用可能なイベントを確認して頂いて、イベント ドリブンにプロダクト連携を試してみてください。
クイック スタート以外でも動かしてみたい場合、Codelab や GitHub にあるチュートリアルを実行してみるのもおすすめです!
明日 19 日目は、hasebe さんによる「Anthos Service Mesh を導入、移行、そして使いこなしてみよう」です。Anthos は自分も触ることが多いので、個人的にも非常に楽しみです!お楽しみに!