[アップデート] Amazon EventBridgeのリージョン間イベント転送が全リージョンで送受信できるようになりました!
みなさん、こんにちは!
福岡オフィスの青柳です。
今年 (2021年) の4月、Amazon EventBridgeに関して発表されたこちらのアップデートを覚えていますでしょうか?
このアップデートによって、単一アカウント内の複数リージョンで発生したAmazon EventBridgeのイベントを一個所のリージョンに集約することができるようになりました。
複数リージョンに展開しているシステムにおいて、「イベントの通知」や「イベントをトリガーとした処理実行」を行う際の管理コストを下げることができる良アップデートでしたね。
ただし、4月のアップデートの時点にはイベントの「送信元」「送信先」の各リージョンが限られていました。
- 送信元に指定可能なリージョン: 10リージョン (バージニア北部、オレゴン、北カリフォルニア、バーレーン、アイルランド、ストックホルム、パリ、東京、シンガポール、シドニー)
- 送信先に指定可能なリージョン: 3リージョン (バージニア北部、オレゴン、アイルランド)
その後、送信元リージョンの制約が緩和されました (時期不明) が、送信先リージョンの制約は変わらず「3リージョン」のままでした。
- 送信元に指定可能なリージョン: 全てのリージョン
- 送信先に指定可能なリージョン: 3リージョン (バージニア北部、オレゴン、アイルランド)
そして、先日、ついに「全てのリージョン (GovCloudと中国を除く)」を送信先として指定できるようになりました!
Amazon EventBridge cross-Region support now expands to more Regions
本記事では、リージョン制限が撤廃されてある意味「完全体」(?) となった「EventBridgeのリージョン間イベント転送」について、利用するメリットや設定手順について解説したいと思います!
本記事では「EventBridgeの同一アカウント・別リージョンへのイベント転送」について解説しています。
「別アカウントへのイベント転送」については、こちらの記事を参照してください。
「同一アカウント・同一リージョン内のイベント転送」については、こちらの記事を参照してください。
リージョン間でイベントを集約できると何が嬉しいの?
リージョン毎にイベントを通知する場合
リージョン間でイベント転送が行えるようになる前は「イベント発生 → 処理 (通知など)」をリージョン内で閉じて行う必要がありました。
例えば、各種AWSサービスで発生した事象をAmazon SNSを使って通知するとします。
AWSサービスの種類によって「直接SNSと連係して通知が行えるもの」「CloudWatch Events (EventBridge) を介してSNSと連係が必要なもの」と違いがありますが、おおむね下図のような構成になります。
この構成ですと、SNSの設定を各リージョン毎に行わなければなりません。
また、SNSのサブスクリプションで設定する通知先は最初に設定した内容でずっと固定という訳ではなく、運用する間に追加・削除・変更が発生する場合が多々ありますよね。
その際に、この図のようにSNSが各リージョンにそれぞれ作成されていると、その都度、各箇所で同じような設定変更を行う必要があります。
- 通知先のメールアドレスの設定が各リージョンで漏れなく最新化されているか・・・
- メールアドレスを追加設定したら、受信者にリージョンの数だけ「サブスクリプションの確認」をやってもらわなくちゃいけない・・・
このような「管理の手間」を軽減するために「リージョン間のイベント集約」が有効なんです!
リージョン間でイベントを集約した場合
リージョン間でイベントを集約する場合は、例えばCloudWatch AlarmsのようにSNSへ直接連係できるサービスであっても、いったんEventBridgeを使ってイベント転送を行います。
各リージョン (複数) のEventBridgeから、集約先リージョン (1つ) のEventBridgeに対してイベントを転送するイメージです。
図にすると以下のようになります。
このような構成にすることで、「リージョン毎にイベントを通知する場合」に懸案となっていた「各リージョンでSNSの設定変更を行わなくてはならない」問題が、一個所のリージョンのみで行えば済むようになりました。
また、集約先のEventBridgeの設定により、イベントのフィルタリングを一個所で行うこともできるようになります。
実際に設定してみる
それでは、実際に設定してみましょう。
さきほどの図をもう少し詳細にして、作成するAWSリソースを説明した図を示します。
「イベントバス」は、EventBridgeにおいてイベントを受信する役目を持つ「パイプライン」です。
リージョン間のイベント集約では「AWS各種サービスからイベントを受信するイベントバス」と「各リージョンから転送されてきたイベントを受信するイベントバス」を明確に分離しています。
(必ずしも分離する必要は無いのですが、特に集約先リージョン (この図では東京リージョン) において混同を避けるためにも、分離することをお勧めします)
- AWS各種サービスで発生したイベントを受信するのは「デフォルト」のイベントバスです。(これは変更できません)
- 集約先リージョンへ転送されたイベントを受信するイベントバスは「デフォルト」と重複しないように「カスタム」イベントバスを作成します。
「イベントルール」は、イベントバスで受信したイベントを、パターンマッチングによるフィルタリングを施した後、後続処理を行うために「ターゲット」に送信するものです。
- 送信側のEventBridgeでは、デフォルトイベントバスで受信したイベントを集約先のカスタムイベントバスに転送するためのイベントルールを設定します。
- 受信側のEventBridgeでは、SNSを使って通知を行うためのルールを設定します。(あるいはLambdaなどを使った処理に連係することもできます)
全体の構成を説明しましたので、ここからは「受信側 (Receiver)」→「送信側 (Sender)」の順に設定を行っていきます。
受信側は「東京リージョン」に作成するものとして進めます。
SNSの設定
EventBridgeの設定を行う前に、SNSのトピックとサブスクリプションを作成しておきます。
- SNSトピック
- タイプ: スタンダード
- 名前:
example-sns-topic
- 各種オプション: (デフォルトのまま)
- SNSサブスクリプション
- トピックARN: (上で作成したSNSトピックのARN)
- プロトコル: Eメール
- エンドポイント: (通知先メールアドレス)
- 各種オプション: (デフォルトのまま)
SNSサブスクリプションのConfirmationも済ませておきます。
EventBridge (Receiver) の設定
カスタムイベントバスの作成
先ほど説明しましたように、受信側のEventBridgeでは「カスタムイベントバス」を作成します。
東京リージョンが選択されていることを確認して、EventBridgeのメニューより「イベントバス」を選択して「イベントバスを作成」をクリックします。
名前のみ設定して「作成」をクリックします。
- 名前:
example-eventbridge-bus-receiver
「カスタムイベントバス」が作成されました。
(ここで表示されるカスタムイベントバスのARNは、後で使用しますので、テキストエディタにコピーするなどして控えて置いてください)
イベントルールの作成
続いて、イベントルールを作成します。
EventBridgeのメニューより「ルール」を選択します。
「イベントバスを選択」で、プルダウンより「example-eventbridge-bus-receiver」を選択してから「ルールを作成」をクリックします。
名前を設定します。
- 名前:
example-eventbridge-rule-receiver
「イベントパターン」を選択して、パターン定義を以下のように設定します。
ここではサンプルとして「EC2インスタンスの状態が『実行中』または『停止済み』に変化した」イベントを通知対象とすることにします。
- イベント一致パターン: サービスごとの事前定義パターン
- サービスプロバイダー: AWS
- サービス名: EC2
- イベントタイプ: EC2 Instance State-change Notification
- 状態: 特定の状態 → 「running」と「stopping」を選択
- インスタンス: 任意のインスタンス
ターゲットを以下のように設定します。
- ターゲット: SNSトピック
- トピック:
example-sns-topic
(最初の手順で作成したSNSトピック名)
その他の項目は変更せずに「作成」をクリックします。
イベントルールが作成されました。
これで受信側の設定は終わりました。
今度は送信側の設定を行います。
送信側は「バージニア北部リージョン」に作成するものとして進めます。
EventBridge (Sender) の設定
送信側ではカスタムイベントバスを作成せず、デフォルトのイベントバスを使います。(したがって、イベントバスの作成手順はありません)
イベントルールの作成
イベントルールを作成します。
バージニア北部リージョンが選択されていることを確認して、EventBridgeのメニューより「ルール」を選択します。
「イベントバスを選択」で、プルダウンより「default」を選択してから「ルールを作成」をクリックします。
名前を設定します。
- 名前:
example-eventbridge-rule-sender
「イベントパターン」を選択して、パターン定義を以下のように設定します。
- イベント一致パターン: サービスごとの事前定義パターン
- サービスプロバイダー: AWS
- サービス名: EC2
- イベントタイプ: EC2 Instance State-change Notification
- 状態: 任意の状態
- インスタンス: 任意のインスタンス
受信側イベントルールのパターン定義と比べると、「イベントタイプ」までは同じ設定内容です。
「状態」については、受信側は「『running』および『stopping』」と指定していたのに対して、送信側は「任意の状態」としています。
通知対象のイベントのフィルタリングは受信側イベントルールで行えるため、送信側ではフィルタリングを行う必然性はありません。
ただし、リージョン間のイベント転送は費用が発生します (※) ので、ある程度イベントを絞り込んでおいた方が良いと思います
したがって、ここでは「イベントタイプ」まで指定しています。
(※ 「カスタムイベント送信の料金: 百万件ごとに1.00USD」+「標準的なリージョン間データ転送料金」)
逆に、あまり細かい条件の絞り込みは行わない方が良いかもしれません。
仮に、通知対象イベントを「running」「stopping」に加えて「terminated」を追加したくなった場合、上記のように設定しておけば受信側のパターン定義を変更するだけで済みます。
しかし、もし送信側のパターン定義で「状態」まで細かく設定していたとしたら、全リージョンで送信側の設定変更が発生してしまいます。
ターゲットを以下のように設定します。
- ターゲット: 別のアカウントまたはリージョンのイベントバス
- イベントバス: (受信側EventBridgeで作成したカスタムイベントバスのARN)
受信側カスタムイベントバスのARNは、控えておいたものをコピー&ペーストするか、もしくは以下の命名規則で入力してください。
arn:aws:events:(受信側のリージョン):(AWSアカウントID):event-bus/(カスタムイベントバスの名前)
最初の方の図で、「カスタムイベントバスへのイベント送信を許可するIAMロール」についての説明が書かれていたと思います。
マネジメントコンソールでEventBridgeの設定を行う場合、このIAMロールを自動的に作成することができます。
「この特定のリソースに対して新しいロールを作成する」を選択してください。(その下のIAMロール名はデフォルトのままで構いません)
なお、自動的に作成されるIAMロールは、以下のように「受信側カスタムイベントバスへのイベント送信 (events:PutEvents) の権限」を持つポリシーがアタッチされます。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "events:PutEvents" ], "Resource": [ "arn:aws:events:ap-northeast-1:123456789012:event-bus/example-eventbridge-bus-receiver" ] } ] }
その他の項目は変更せずに「作成」をクリックします。
イベントルールが作成されました。
これで送信側の設定も終わりました。
動作を確認する
それでは動作を確認してみましょう。
EC2インスタンスの状態変化を通知するように設定しましたので、実際にEC2インスタンスを起動・停止してみて、通知が行われることを確認します。
「バージニア北部」リージョンで、何でもよいのでEC2インスタンスを起動してみてください。
以下のようなメールが届くのが確認できましたでしょうか?
- 件名:
AWS Notification Message
- 送信元:
AWS Notifications
本文はイベントを表すのJSONが記載されています。(改行が無くて見辛いと思いますので、以下では整形して見易くしています)
{ "version": "0", "id": "2a198a45-7432-5e58-4f90-3ba093dc6736", "detail-type": "EC2 Instance State-change Notification", "source": "aws.ec2", "account": "123456789012", "time": "2021-11-28T09:28:42Z", "region": "us-east-1", "resources": [ "arn:aws:ec2:us-east-1:123456789012:instance/i-052548b65230285b6" ], "detail": { "instance-id": "i-052548b65230285b6", "state": "running" } }
同様にして、EC2インスタンスを停止してみて、通知が行われることを確認してください。
で、リージョン間でイベントを集約できると何が嬉しいの?(再び)
EventBridgeを使ったリージョン間のイベント集約を使うメリットの一つとして、「EventBridgeだけで仕組みが完結している」ことが挙げられると思います。
AWSのサービスの多くがEventBridgeに対応していますし、EventBridgeに対応したサードパーティー製品・サービスも増えつつあります。
それらのサービス・製品で、複数リージョンに跨ったリソースのイベントを通知したり、イベントをトリガーに処理を実行したい場合、今回の「EventBridgeによるリージョン間のイベント集約」の手法を会得しておけば、「受信するイベントパターンの定義」と「通知先・連係先のサービスの指定」を変更するだけで対応することができます。
以下のような場面で、複数リージョンでAWS環境を構築・AWSリソースを作成する機会が多くなっているのではないかと思います。
- 事業の海外展開により、複数のリージョンでAWSを利用している
- バックアップ・可用性 (DR構成など) の目的で、複数のリージョンにAWS環境を構築している
- セキュリティや内部統制関連のAWSサービスで、全リージョンに適用することが推奨されている (CloudTrail、GuardDutyなど)
このような時に、リージョン毎に通知や連係の設定を行うのは、管理コストの増大や管理の複雑さによるミスを招いてしまいます。
是非、今回ご紹介した「EventBridgeによるリージョン間のイベント集約」を活用して頂きたいと思います!
※ なお、AWSサービスによっては、例えば「AWS Security Hub」のように、サービス自体でリージョン間の集約機能を備えているものもあったりします。EventBridgeを使ったリージョン間イベント集約を行うべきか別の方法を使うべきかは、都度検討した方がよろしいかと思います。
おわりに
さて、今回は「EventBridgeのリージョン間イベント転送」のメリットや設定手順を解説しましたが、「送信側」のリージョンが多い場合、各リージョンで同じような設定を繰り返すのは大変になると思います。
そこで、次回は「CloudFormation」や「Terraform」などのIaC (Infrastructure as Code) を使った「複数リージョンの一括設定」について解説できればと思います。
2021/11/30 追記
CloudFormation/Terraformによる「複数リージョンの一括設定」について、ブログ記事を書きました!
是非こちらも併せてご確認ください。