はじめに:SaaSの「サイロ化」を防ぐ、イベント駆動という血流
マイクロサービスアーキテクチャを採用したSaaS開発が進むにつれ、我々は新たな課題に直面します。それは、サービス間の通信が複雑に絡み合い、システム全体が「見えないスパゲッティ」状態に陥るリスクです。一つのサービスの変更が、予期せぬ別のサービスに影響を及ぼし、俊敏性は失われていきます。
この課題を解決し、システム全体に柔軟性と回復力という「血流」を送り込むのが、イベント駆動アーキテクチャ(EDA)であり、その心臓部となるのがAmazon EventBridgeです。
EventBridgeは、サービス間の直接的な依存関係を断ち切り、「イベント」を介した非同期通信を実現します。これにより、各サービスは独立して進化でき、システム全体としてスケールすることが可能になります。
この記事では、マルチテナントSaaSという特有の環境において、EventBridgeをいかに設計し、テナントのイベントを安全かつ効率的にルーティングするか、その具体的な実装パターンとベストプラクティスを徹底解説します。
パターン1:共有イベントバスモデル(コスト効率とシンプルさの追求)
これは、全テナントのイベントを単一のイベントバスに集約する、最も一般的でコスト効率に優れたアプローチです。
アーキテクチャ解説
graph TD
subgraph "テナントA"
ServiceA1 --> |イベント発行| Bus
end
subgraph "テナントB"
ServiceB1 --> |イベント発行| Bus
end
subgraph "共有イベントバス"
Bus(fa:fa-exchange-alt Shared Event Bus)
end
subgraph "ターゲット"
RuleA(ルール: tenantId == 'A') --> TargetA[Lambda for A]
RuleB(ルール: tenantId == 'B') --> TargetB[SQS for B]
end
Bus --> RuleA
Bus --> RuleB
実装の核心
-
イベントに
tenantId
を含める: 発行する全てのイベントのdetail
フィールドに、"tenantId": "テナントAのID"
のような識別子を必ず含めます。これが、後続の処理でテナントを識別するための唯一の鍵となります。 -
ルールでフィルタリング: EventBridgeのルールを作成し、イベントパターンの
detail.tenantId
フィールドを照合します。これにより、「テナントAのイベントは、テナントA専用のLambda関数にのみルーティングする」といった制御が可能になります。
メリット・デメリット
- メリット: 管理するバスが一つで済むため運用がシンプル。リソース共有によりテナントあたりのコストを低く抑えられます。
- デメリット: あるテナントのイベントが急増すると、バス全体のスループット制限に達し、他テナントに影響を及ぼす「ノイジーネイバー」問題のリスクがあります。また、全イベントが同じバスを通過するため、厳格なコンプライアンス要件を持つテナントには不向きな場合があります。
パターン2:テナントごとイベントバスモデル(セキュリティと分離の徹底)
これは、テナントごとに専用のイベントバスをプロビジョニングすることで、最高の分離レベルを実現するアプローチです。
アーキテクチャ解説
graph TD
subgraph "テナントA"
ServiceA1 --> BusA(fa:fa-exchange-alt Event Bus for A)
BusA --> RuleA --> TargetA[Lambda for A]
end
subgraph "テナントB"
ServiceB1 --> BusB(fa:fa-exchange-alt Event Bus for B)
BusB --> RuleB --> TargetB[SQS for B]
end
実装の核心
テナントが新規契約(オンボーディング)された際に、AWS CDKやTerraformといったIaCツールを使い、プログラムでそのテナント専用のイベントバスと関連リソース一式を自動的にデプロイします。
メリット・デメリット
- メリット: テナント間のデータパスが物理的に分離されるため、セキュリティが非常に強固です。ノイジーネイバー問題も完全に解消されます。
- デメリット: テナント数に比例してAWSリソースが増加するため、コストが高騰し、運用管理も複雑になります。
【セキュリティ最重要】鉄壁のテナント分離を実現するIAMポリシー
特に共有イベントバスモデルでは、IAMポリシーによる厳格なアクセス制御が不可欠です。カスタムイベントバスには、必ずリソースベースのポリシーをアタッチし、意図しない発行元からのイベントをブロックしましょう。
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowSpecificRoleToPublish",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/MySaaSApplicationRole"
},
"Action": "events:PutEvents",
"Resource": "arn:aws:events:us-east-1:123456789012:event-bus/MySharedSaaSBus",
"Condition": {
"StringEquals": {
"events:source": "com.my-app.orders"
}
}
}]
}
このポリシーは、「MySaaSApplicationRole
というIAMロールから」かつ「source
がcom.my-app.orders
であるイベント」のみ、このイベントバスへの発行を許可します。
堅牢なパイプラインの構築:エラーハンドリングと監視
- デッドレターキュー(DLQ): ターゲット(Lambdaなど)での処理が失敗した場合に備え、イベントをSQSキューに退避させるDLQを設定します。これにより、データの損失を防ぎ、後から原因調査や再処理が可能になります。
- 再試行ポリシー: ネットワークの一時的なエラーなどで処理が失敗した場合に備え、ターゲットごとに再試行回数と間隔を適切に設定します。
- CloudWatchメトリクス:
FailedInvocations
(失敗した呼び出し)やThrottledRules
(スロットリングされたルール)といったメトリクスを常に監視し、アラームを設定することで、システムの異常を早期に検知できます。
結論:あなたのSaaSに最適なイベントルーティング戦略は?
観点 | 共有イベントバス | テナントごとイベントバス |
---|---|---|
コスト効率 | ★★★★★ | ★★☆☆☆ |
テナント分離 | ★★★☆☆ | ★★★★★ |
運用シンプルさ | ★★★★☆ | ★★☆☆☆ |
推奨フェーズ | 初期・成長期 | 成熟期・エンタープライズ |
多くのSaaSにとって、最も現実的で効果的なのはハイブリッド戦略です。つまり、最初は「共有イベントバスモデル」で迅速かつ低コストにサービスを開始し、ビジネスが成長して、より高いセキュリティやパフォーマンスを求めるエンタープライズ顧客が現れた際に、そのテナントにのみ「専用イベントバス」を提供するというアプローチです。
EventBridgeを使いこなすことは、SaaSアーキテクチャの拡張性と信頼性を担保する上で不可欠です。この記事を参考に、あなたのビジネスに最適なイベントパイプラインを設計してください。
コメント