[アップデート]S3のオブジェクトレベルのイベント通知がAmazon EventBridgeとシームレスに統合されました! #reinvent

S3イベントドリブンなサーバレスアプリケーションが作りやすくなったぞ!神アプデ!
2021.11.30

こんにちは、おんづか(@onzuka_muscle)です!

S3イベントドリブンなサーバレスアプリケーションがグッと構成しやすくなる神アプデがきました。

You can now use Amazon S3 Event Notifications with Amazon EventBridge to build, scale, and deploy event-driven applications based on changes to the data you store in S3. This makes it easier to act on new data in S3, build multiple applications that react to object changes simultaneously, and replay past events, all without creating additional copies of objects or developing new software.

S3に保存するデータの変更に基づいてイベントドリブンなアプリケーションを構築、拡張、展開できるようになりました

オブジェクトの変更に同時に反応する複数のアプリケーションを構築したり、過去のイベントを再生したりすることが容易に

Amazon S3 Event Notifications with Amazon EventBridge allow you to make use of advanced filtering and routing capabilities and send events to 18 targets including AWS Lambda, Amazon Kinesis, AWS Step Functions, and Amazon SQS. S3 Event Notifications with EventBridge can simplify your architecture by allowing you to match any attribute, or a combination of attributes, for objects in an S3 event.

「AWS Lambda、Amazon Kinesis、AWS Step Functions、Amazon SQSを含む18のターゲットにイベントを送信することができます」

「S3イベント内のオブジェクトに対して、任意の属性、または属性の組み合わせをマッチさせることができるため、アーキテクチャを簡素化することができます」

This makes it possible for you to filter events by object size, time range, or other event metadata fields before invoking a target AWS Lambda function or other destinations.

「対象となるAWS Lambda関数などを起動する前に、オブジェクトサイズや時間範囲などのイベントメタデータフィールドでイベントをフィルタリングすることが可能に」

なるほど、EventBridgeに直接送信できるようになったことでフィルタリング機能、ターゲット選択、他機能といったEventBridgeのメリットを享受できるようになったので便利になったよ〜!ということらしいです。

早速、試してみます!

やってみた

S3でEventBridgeの通知を有効にする

早速、イベントルールを書きたいところですがS3側での設定が必須になりますので要注意。ポチポチするだけです。

対象のバケット>プロパティ>Amazon EventBridge

オンにします。

イベントルール作成する

EventBridgeの画面よりイベントルールを作成します。

通知されることを手っ取り早く試したかったのでフィルタは何も設定せずに「任意のイベント」を選択しました。

SNSを使ってEメールに送信してみます。

  • イベントパターン
{
  "source": ["aws.s3"],
  "detail-type": ["Object Access Tier Changed", "Object ACL Updated", "Object Created", "Object Deleted", "Object Restore Completed", "Object Restore Expired", "Object Restore Initiated", "Object Storage Class Changed", "Object Tags Added", "Object Tags Deleted"]
}

イベントを抜き出して縦に並べてみました。

  • Object Access Tier Changed
  • Object ACL Updated
  • Object Created
  • Object Deleted
  • Object Restore Completed
  • Object Restore Expired
  • Object Restore Initiated
  • Object Storage Class Changed
  • Object Tags Added
  • Object Tags Deleted

バケットにファイルをアップロードする

アップロード完了後に数秒で通知がきました!

{
  "version": "0",
  "id": "436cee3f-1218-b9b1-293d-cc0506eeba5f",
  "detail-type": "Object Created",
  "source": "aws.s3",
  "account": "XXXXXXXXXXXX",
  "time": "2021-11-30T03:56:14Z",
  "region": "us-east-1",
  "resources": ["arn:aws:s3:::onzuka-test-eventbridge"],
  "detail": {
    "version": "0",
    "bucket": { "name": "onzuka-test-eventbridge" },
    "object": {
      "key": "スクリーンショット 2021-11-30 12.54.45.png",
      "size": 93617,
      "etag": "035bf1fc4b0a420b23c170769f6b7dfe",
      "sequencer": "0061A5A0DE6C9F3646"
    },
    "request-id": "DMGFBG77TRA4ZWAJ",
    "requester": "XXXXXXXXXXXX",
    "source-ip-address": "14.12.5.225",
    "reason": "PutObject"
  }
}

オブジェクトの情報が色々と載ってますね!

次はタグを付与してみました。

{
  "version": "0",
  "id": "4b46b0e5-52b7-189b-b747-48edaa65a144",
  "detail-type": "Object Tags Added",
  "source": "aws.s3",
  "account": "XXXXXXXXXXXX",
  "time": "2021-11-30T03:58:52Z",
  "region": "us-east-1",
  "resources": ["arn:aws:s3:::onzuka-test-eventbridge"],
  "detail": {
    "version": "0",
    "bucket": { "name": "onzuka-test-eventbridge" },
    "object": {
      "key": "スクリーンショット 2021-11-30 12.54.45.png",
      "etag": "035bf1fc4b0a420b23c170769f6b7dfe"
    },
    "request-id": "3QXHPQXTG4AFDSXR",
    "requester": "XXXXXXXXXXXX",
    "source-ip-address": "14.12.5.225"
  }
}

最後にオブジェクトを削除してみました。

{
  "version": "0",
  "id": "de101aa3-9e19-76e4-0004-7e3e156424a4",
  "detail-type": "Object Deleted",
  "source": "aws.s3",
  "account": "XXXXXXXXXXXX",
  "time": "2021-11-30T03:59:23Z",
  "region": "us-east-1",
  "resources": ["arn:aws:s3:::onzuka-test-eventbridge"],
  "detail": {
    "version": "0",
    "bucket": { "name": "onzuka-test-eventbridge" },
    "object": {
      "key": "スクリーンショット 2021-11-30 12.54.45.png",
      "sequencer": "0061A5A19B0413426C"
    },
    "request-id": "2RFXSEHPDPJX8MKD",
    "requester": "XXXXXXXXXXXX",
    "source-ip-address": "14.12.5.225",
    "reason": "DeleteObject",
    "deletion-type": "Permanently Deleted"
  }
}

フィルタの例

バケットで絞る

{
  "source": ["aws.s3"],
  "detail-type": ["Object Created", "Object Deleted"],
  "detail": {
    "bucket": {
      "name": ["onzuka-test-eventbridge"]
    }
  }
}

オブジェクトのサイズで絞る

{
  "source": ["aws.s3"],
  "detail-type": ["Object Created", "Object Deleted"],
  "detail": {
    "object": {
      "size": [
        {
          "numeric": ["<=", 1048576]
        }
      ]
    }
  }
}

プレフィックスマッチを使う

S3にはフォルダの概念はない(※下記ブログ参照)のですがオブジェクト名のプレフィックスマッチを使えば「特定フォルダ内のオブジェクトのみ対象にする」といったイメージのフィルタができます。

{
  "source": ["aws.s3"],
  "detail-type": ["Object Created", "Object Deleted"],
  "detail": {
    "object": {
      "key": [{ "prefix": "uploads/" }]
    }
  }
}

その他

prefixだけでなく他のコンテンツフィルタリングを使ってもっと高度なフィルタリングも実現可能です。

補足説明

コスト

Amazon EventBridge の料金

100万イベントごとに1.00USDです。(2021/11/30時点)

これまでとどう違う?

今までは下記2パターンの対応方法がありました。

At this point you might be thinking that you already had the ability to react to changes in your S3 objects, and wondering what’s going on here. Back in 2014 we launched S3 Event Notifications to SNS Topics, SQS Queues, and Lambda functions. This was (and still is) a very powerful feature, but using it at enterprise-scale can require coordination between otherwise-independent teams and applications that share an interest in the same objects and events. Also, EventBridge can already extract S3 API calls from CloudTrail logs and use them to do pattern matching & filtering. Again, very powerful and great for many kinds of apps (with a focus on auditing & logging), but we always want to do even better.

  • S3のイベント通知機能を使う
    • Lambda,SNS,SQSのみターゲットに選択できる
    • 高度なフィルタリングはできない、やれることはシンプル
  • CloudTrailイベントをEventBridgeで拾う
    • CloudTrailでバケットのオブジェクトレベルの認証を有効化する必要あり(追加の課金発生)

前者は制約が大きく、後者は一旦CloudTrailイベントを経由する必要がありましたが、今回のアプデでそれらが解決された形になります!

メリット

改めてEventBridgeに直接イベント送信できるメリットをまとめます。

高度なフィルタリング

オブジェクトサイズ、キー名、時間範囲など、多くの追加メタデータフィールドでフィルタリングできます。

S3にコールバックするようなLambdaを作成せずともEventBridgeでフィルタできるようになったので手間も減りましたし、マッチしたイベントのみ通知されるのでコスト減にもなります。

複数のターゲット

同じイベント通知を、Step Functions、Kinesis Firehose、Kinesis Data Streams、HTTPターゲットなど、18のAWSサービスの中から、APIデスティネーション経由で選択してルーティングすることができます。

高速で信頼性の高い呼び出し

パターンのマッチング(およびターゲットの呼び出し)は、高速に直接的に行われます。

また、S3はイベントをEventBridgeに一度だけ配信するので、アプリケーションの信頼性が向上します。

EventBridgeの他の機能を利用できる

下記のreplay機能のようなEventBridgeに備わっている機能を利用できます!

EventBridgeのこれからくるアップデートの恩恵にも期待できますね。

所感

これまでオブジェクトレベルのイベントは通知するには面倒だったところがEventBridgeとシームレスに統合されてラクに構築可能になりました。

サーバレスアーキテクチャでS3は出番が多いので個人的に神アプデと感じます。