EventBridge を使ったイベント駆動アーキテクチャを設計・運用するうえでの実践的な指針をまとめたもの。


目次

  1. コンポーネントの使い分け
  2. イベント設計
  3. イベントバスの構成
  4. ルールとフィルタリング
  5. 信頼性とエラーハンドリング
  6. アーカイブとリプレイ
  7. セキュリティ
  8. 可観測性
  9. クォータとパフォーマンス
  10. コスト最適化
  11. 開発・運用
  12. よくあるアンチパターン

1. コンポーネントの使い分け

コンポーネント用途選ぶ場面
Event Busルールに基づく多対多のイベントルーティング複数のコンシューマーにファンアウトしたい、サービス間を疎結合にしたい
Pipes1 ソース → 1 ターゲットのポイントツーポイント連携(フィルタ・エンリッチ付き)SQS / Kinesis / DynamoDB Streams などから特定ターゲットへ流すだけ。Lambda の「つなぎコード」を消したい
Scheduler時刻ベース・定期実行のタスク起動cron / rate / 1 回限りの実行。大量のスケジュール管理
Scheduled Rules(旧来)ルールでの定期実行新規では基本的に Scheduler を優先
  • 定期実行は EventBridge Scheduler を使う。 タイムゾーン指定、1 回限りのスケジュール、フレキシブルタイムウィンドウ、リトライ/DLQ 設定、大量スケジュールへのスケールに対応しており、Scheduled Rules より機能が豊富。SDK 統合で多数の AWS API を Lambda なしで直接呼べる。
  • 単純な 1 対 1 連携は Pipes を検討する。 ポーリング・バッチ・フィルタ・エンリッチメント・変換をマネージドで行えるため、中継用の Lambda を減らせる。

拡張版 Custom event bus について

2026年9月に、強化された Custom event bus が登場した(従来のバスは「Custom event bus - classic」に改称、既存 API は変更なし)。主な特徴:

  • アカウント間でのバス共有
  • 厳密な順序保証(strict ordering)とコンテンツベースの重複排除
  • CloudEvents など JSON ベースのイベント形式をスキーマを変えずに発行できる新しい発行 API
  • 組み込みのリテンション(デフォルト 24 時間、最大 1 年まで延長可)
  • フィルタと配信先を定義する新しい Subscriber リソース
  • イベント数ではなくデータ転送量に基づく課金

指針: 順序保証・長期リテンション・マルチアカウント共有が必要な新規ワークロードでは拡張版を評価する。ただし提供リージョンが限られているため、利用予定リージョンでの提供状況・料金・既存ツール(IaC、監視)の対応状況を確認してから採用を決めること。既存の classic バスを急いで移行する必要はない。


2. イベント設計

スキーマとエンベロープ

  • source と detail-type に命名規約を設ける。
    • source: 逆ドメイン形式で発行元を表す(例: com.example.orders)。aws. プレフィックスは AWS 予約。
    • detail-type: 過去形の業務イベント名(例: OrderPlaced, PaymentFailed)。
  • detail 内にメタデータを持たせる。 バージョン、相関 ID、冪等性キーなどを定型化する。
{
  "source": "com.example.orders",
  "detail-type": "OrderPlaced",
  "detail": {
    "metadata": {
      "version": "1",
      "idempotencyKey": "order-12345-placed",
      "correlationId": "c0a8-...",
      "domain": "orders"
    },
    "data": {
      "orderId": "12345",
      "customerId": "C-001",
      "totalAmount": 4800,
      "currency": "JPY"
    }
  }
}
  • スキーマのバージョニングを最初から決めておく。 後方互換な変更(フィールド追加)を基本とし、破壊的変更は新しい detail-type またはバージョンで出す。
  • Schema Registry とスキーマディスカバリを活用する。 スキーマのドキュメント化とコードバインディング生成ができる。ただしディスカバリは開発・検証環境で有効にし、本番では必要に応じて(取り込みに課金されるため)。
  • 業界標準形式を検討する。 チーム横断・社外連携があるなら CloudEvents のような形式を採用すると相互運用しやすい。

ペイロードの中身

  • 「通知(thin)」か「状態転送(fat)」かを意図的に選ぶ。
    • Thin イベント: ID だけを載せ、詳細はコンシューマーが取りに行く。結合は緩いがコールバックが発生する。
    • Fat イベント: 必要な情報を載せ、コンシューマーは追加取得不要。プロデューサー側のスキーマ変更の影響が大きい。
  • ペイロード上限は 1 MB に拡大された(一部リージョンを除く)が、大きなデータは S3 に置き参照を渡す(Claim Check パターン) 方が、コストと転送量の面で依然有利なことが多い。
  • 個人情報・機密情報を不用意に載せない。 多数のコンシューマーやアーカイブに残る前提で設計する。

3. イベントバスの構成

  • デフォルトバスは AWS サービスイベント用、アプリケーションイベントはカスタムバスへ。 権限・ルールの境界が明確になる。
  • ドメイン(境界づけられたコンテキスト)単位でバスを分けるか、組織共通の単一バスにするかを決める。
    • 単一の中央バス: 発見しやすく、ガバナンスを一元化できる。
    • ドメイン別バス: 所有権が明確で、影響範囲を限定できる。
  • マルチアカウントでは中央バス(ハブ)+各アカウントのバス(スポーク)を検討する。
    • クロスアカウントは、ターゲットに別アカウントのバスを指定するか、直接クロスアカウントターゲット(SQS / Lambda など)を使う。
    • リソースポリシーで aws:PrincipalOrgID などを使い、Organizations 内に送信元を限定する。
  • クロスリージョン配信は DR やリージョン集約に使えるが、遅延とデータ転送コストを考慮する。

4. ルールとフィルタリング

  • イベントパターンはできるだけ具体的に書く。 source と detail-type は必ず指定し、必要なら detail のフィールドまで絞る。曖昧なパターンは意図しないイベントにマッチし、無限ループやコスト増を招く。
  • コンテンツフィルタリングを活用する。 prefix / suffix / anything-but / numeric / exists / wildcard / $or などで、ターゲット側でのフィルタ処理を減らす。
  • 無限ループに注意する。 ルールのターゲットが、同じルールにマッチするイベントを発生させないようにする(例: S3 オブジェクト作成 → Lambda が同じバケットに書き込む)。
  • 入力変換(Input Transformer)でターゲットが必要な形に整形する。 ターゲット側の解析コードを減らせる。
  • 1 ルールあたりのターゲット数上限(5)を意識する。 それ以上のファンアウトは SNS / 別バスを挟むか、ルールを分ける。
  • ルール名・説明に所有者と用途を明記し、タグを付ける。 誰のルールか分からない状態を避ける。
  • パターンはテストする。 TestEventPattern API やコンソールのサンドボックスで、マッチ・非マッチの両方を CI で検証する。

5. 信頼性とエラーハンドリング

配信保証の前提

  • EventBridge の配信は at-least-once(少なくとも 1 回)。重複配信は起こりうる。
  • classic バスでは 順序は保証されない。順序が必要なら、拡張版バスの strict ordering、SQS FIFO、Kinesis などを使う。

冪等性

  • コンシューマーは必ず冪等に実装する。 冪等性キー(イベント ID や業務キー)を DynamoDB の条件付き書き込みなどで記録し、重複処理を防ぐ。Powertools for AWS Lambda の Idempotency ユーティリティが便利。

リトライと DLQ

  • すべてのターゲットに DLQ(SQS)を設定する。 デフォルトでは最大 24 時間・185 回リトライ後にイベントが破棄される。
  • リトライポリシー(最大イベント経過時間・最大リトライ回数)をワークロードに合わせて調整する。 古いイベントが意味をなさない処理では短くする。
  • DLQ を監視し、再処理手順(runbook)を用意する。 DLQ にメッセージが入ったらアラートを出す。

バッファリング

  • Lambda を直接ターゲットにするより、SQS を挟む方が安全な場合が多い。 バーストの吸収、同時実行数の制御、部分失敗時の再処理がしやすい。
  • API Destinations ではレート制限(invocation rate)を設定する。 外部 API の上限を超えないようにする。

発行側

  • PutEvents のレスポンスの FailedEntryCount を必ず確認する。 HTTP 200 でも一部のエントリが失敗していることがある。失敗分はリトライする。
  • バッチ発行(最大 10 件/リクエスト)でスループットとコストを最適化する。
  • 確実な発行が必要なら Transactional Outbox パターンを使う。 DB 更新とイベント発行の不整合を防ぐ(DynamoDB Streams → Pipes → EventBridge など)。

6. アーカイブとリプレイ

  • 重要なバスにはアーカイブを設定する。 障害復旧、バグ修正後の再処理、新しいコンシューマーへのデータ投入に使える。
  • 保持期間を明確に決める。 無期限はコストとコンプライアンスの両面で注意。
  • アーカイブ対象をイベントパターンで絞る。 すべてを保存する必要はない。
  • リプレイ時は冪等性が前提。 リプレイされたイベントは replay-name フィールドで判別できるため、外部通知などの副作用は抑制できるようにしておく。
  • 拡張版バスでは組み込みリテンションがあるため、要件次第でアーカイブとの役割分担を検討する。

7. セキュリティ

  • 最小権限の原則。
    • プロデューサーには対象バスへの events:PutEvents のみを付与し、必要なら events:source 条件キーで発行できる source を制限する。
    • ルールのターゲット呼び出し用 IAM ロールも、ターゲットごとに最小権限で作る。
  • バスのリソースポリシーで送信元アカウント/組織を限定する。
  • 暗号化。 機密性の高いデータを扱う場合はカスタマー管理 KMS キーで暗号化する(アーカイブ・DLQ も含めて)。
  • API Destinations の認証情報は Connection 経由で管理する。 認証情報は Secrets Manager に保存される。コードやパラメータに直書きしない。
  • VPC 内からの発行には VPC エンドポイント(PrivateLink)を使う。
  • CloudTrail で管理 API(ルールの作成・変更・削除など)を監査する。

8. 可観測性

  • CloudWatch メトリクスを監視・アラーム化する。
    • FailedInvocations: ターゲット呼び出しの失敗
    • ThrottledRules: スロットリング
    • DeadLetterInvocations: DLQ への送信
    • InvocationsFailedToBeSentToDlq: DLQ 送信の失敗(イベント消失のサイン、最重要)
    • MatchedEvents / Invocations: 想定どおり流れているか(急減も異常)
    • IngestionToInvocationStartLatency: 遅延
  • 相関 ID を全イベントに含め、構造化ログで追跡できるようにする。
  • AWS X-Ray のトレースコンテキストを伝播させる。
  • ログ出力を有効化する。 バスのログ機能でイベントの取り込み・配信状況を確認できる。デバッグ時は CloudWatch Logs をターゲットにした「キャッチオール」ルールを一時的に作るのも有効(本番で常時有効にする場合はコストと機密情報に注意)。
  • イベントカタログを整備する。 どのイベントを誰が発行し、誰が購読しているかを可視化する(Schema Registry や EventCatalog などのツール)。

9. クォータとパフォーマンス

  • PutEvents のスループットクォータ(リージョン・アカウント単位)を確認し、必要なら事前に引き上げ申請する。
  • ターゲット側の同時実行・スロットリングがボトルネックになりやすい。 Lambda の予約同時実行数、外部 API のレート制限と合わせて設計する。
  • ルール数・ターゲット数の上限を把握する。 ルールが増えすぎる場合はバスの分割を検討する。
  • EventBridge は低遅延だが、ミリ秒単位のリアルタイム性が必須の処理には向かない。その場合は Kinesis や直接呼び出しを検討する。

10. コスト最適化

  • 不要なイベントを発行しない・不要なルールを作らない。 カスタムイベントは発行件数で課金される(classic バスの場合。拡張版はデータ転送量ベース)。
  • ペイロードサイズを意識する。 classic バスでは 64 KB 単位で 1 イベントとして課金される。
  • AWS サービスイベント(デフォルトバス)は無料だが、クロスアカウント配信やアーカイブには課金される。
  • アーカイブの対象と保持期間を絞る。
  • Pipes のフィルタで早めに絞り込む。 フィルタで除外されたイベントは課金対象外。
  • スキーマディスカバリは本番で常時有効にしない。

11. 開発・運用

  • IaC(CloudFormation / CDK / SAM / Terraform)で管理する。 コンソールでの手動変更はドリフトの原因になる。
  • ルールとターゲットは、コンシューマー側のスタックで所有する。 プロデューサーはコンシューマーを知らない、という疎結合の原則を IaC の構成にも反映させる。
  • 環境(dev / stg / prod)ごとにバスまたはアカウントを分離する。
  • テスト戦略。
    • ユニット: イベントパターンのテスト、ハンドラーのテスト
    • 統合: 実際のバスにテストイベントを送り、テスト用ルール(SQS や CloudWatch Logs をターゲット)で受信を検証
    • 契約テスト: プロデューサーとコンシューマー間のスキーマ互換性
  • イベントのドキュメント化と変更プロセスを定める。 破壊的変更の事前告知、旧バージョンの非推奨期間など。

12. よくあるアンチパターン

アンチパターン問題対策
コンシューマーが冪等でない重複配信で二重処理冪等性キーで重複排除
DLQ 未設定リトライ枯渇でイベントが無言で消える全ターゲットに DLQ + アラーム
PutEvents の部分失敗を無視イベントの取りこぼしFailedEntryCount を確認してリトライ
曖昧なイベントパターン意図しないマッチ、無限ループsource / detail-type を必ず指定
EventBridge をリクエスト/レスポンスに使う同期応答が必要な処理には不向きAPI Gateway / 直接呼び出し、または非同期化
順序に依存した処理を classic バスで実装順序が保証されない拡張版バスの順序保証 / SQS FIFO / Kinesis
単純な 1:1 連携を Event Bus + Lambda で実装余計なコードとコストPipes を使う
定期実行を Scheduled Rules で大量に作成管理しにくい、機能不足EventBridge Scheduler
巨大なペイロードをそのまま流すコスト増、機密情報の拡散Claim Check パターン

参考資料

0件のページ