エンジニア

2022.09.06

EventBridgeで別リージョンのイベントを拾いたい!

こんにちは。

早速ですが、AWSを利用する中で東京リージョン(以下ap-northeast-1)に対応していないサービスに出会ったことがある方は多いのではないでしょうか。その際仕方なく別リージョンを選択することになるのですが、EventBridgeでそのリージョンのイベントを検知するのに一癖あったので備忘録がてらまとめます。AWS初心者(私を含む)の方々にも参考にしていただけるような説明にしたいので、玄人の方達からすると無駄な部分が多いかもしれません。不要な箇所は読み飛ばしていただけますと幸いです。

目標

今回はバージニア北部リージョン(以下us-east-1)でS3バケットが作成された時にap-northeast-1のlambdaを動かすことを目標とします。S3バケットの作成はap-northeast-1でも行えますが、簡単に確認できるためこちらを選択しました。

手順

別リージョンのイベントを拾う手順を簡単にまとめました。送信先リージョンと送信元リージョンはみなさんの環境に合わせて読み替えてください。本記事では送信先リージョンをap-northeast-1、送信元リージョンをus-east-1とします。

  1. 送信先リージョン(ap-northeast-1)でイベントバスを作成
  2. 1.で作成したイベントバスを指定して送信先リージョン(ap-northeast-1)でルールを作成
  3. 送信リージョン(us-east-1)でルールを作成

実践

lambdaの作成

EventBridgeの設定をする前にターゲットとなるlambdaを作成しましょう。ここではpythonで書いていますが、動けばなんでも良いです。

マネジメントコンソールから「lambda > 関数 > 関数の作成」に進み、画像のように設定したら「関数の作成」をクリックします。この時、右上に東京(ap-northeast-1)と表示されていることを確認します。

関数が表示されたら「コードソース」の中身を以下のように変更し、Deployをクリックします(関数が実行されたかどうかをわかりやすくするためなので、なくても構いません)。

import json

def lambda_handler(event, context):
    print('success') # この行を追加
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

これでlambdaの作成は完了です。

送信先リージョン(ap-northeast-1)でイベントバスを作成

「Amazon EventBridge > イベントバス > イベントバスを作成」で任意の名前を入力後「作成」をクリックします。lambda同様、東京(ap-northeast-1)が選択されていることを確認してください。

「Amazon EventBridge > イベントバス」の「カスタムイベントバス」に先ほど作成したイベントバスが表示されていることが確認します。

イベントバスを指定して送信先リージョン(ap-northeast-1)でルールを作成

「Amazon EventBridge > ルール」の「イベントバスを選択」で先ほど作成したイベントバスを選択し、「ルールを作成」をクリックします。またまた任意の名前を設定後「次へ」をクリックします。

画像のように「イベントパターン」を設定します。

「パターンを編集」に直接書き込んでも良いです。

{
  "source": ["aws.s3"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["s3.amazonaws.com"],
    "eventName": ["CreateBucket"]
  }
}

ターゲットに先ほど作成したlambdaを指定し「次へ」をクリックします。タグの設定は不要ですのでスキップして構いません。「レビューと作成」で設定の確認をして、問題なければ「ルールの作成」をクリックします。

作成したルールが「Amazon EventBridge > ルール」に表示されていることを確認します。

送信リージョン(us-east-1)でルールを作成

us-east-1に移動して、先ほどと同様の手順で送信元のイベントルールを作成します。ここではイベントバスはdefaultを使用します。名前はまたまたまた任意です。

「イベントパターン」も先ほどと同様のものを設定します。

「ターゲットを選択」は先ほどと異なります。「ターゲットタイプ」で「EventBridge イベントバス」を選択し、「別のアカウントまたはリージョンのイベントバス」に先ほどap-northeast-1で作成したイベントバスのARNを入力します。

「タグの設定」をスキップしたら「レビューと作成」で設定の確認をして、問題なければ「ルールの作成」をクリックします。

確認

これで全ての設定が完了しました。実際にS3バケットを作成してlambdaが実行されるかを確認しましょう。

us-east-1リージョンでバケットを作成します。

「Lambda > 関数 > {作成した関数名}」で「モニタリング」を選択し「CloudWatchのログを表示」をクリックします。トリガーとしてEventBridgeが設定されていることも確認できます(赤枠)。

「ログストリーム」で最新のログを開きます。無事「success」が表示されていることが確認できました。

今回はバケット作成のみを対象としているので、バケット削除時やオブジェクト作成時には実行されません。気になる方は先ほど作成したテスト用バケットを削除してみてください。lambdaが実行されないことが確認できます。

おまけ serverless frameworkでの実装

serverless frameworkを使用しているケースも多いと思いますので、serverless frameworkでの実装にも軽く触れておきます。

送信元リージョン(us-east-1)用のymlでは

  • ルール
  • IAMロール
  • ポリシー

の3つを設定します。イベントバスはdefaultを使用するので不要です。

Resources:
    testEvent:
      Type: AWS::Events::Rule
      Properties:
        EventPattern: 
          source: 
            - {source}
          detail-type:
            - {detail-type}
          detail: 
            eventType: 
              - {eventType}
        Targets:
            - Arn: {送信先リージョンのイベントバスARN}
              Id: {任意のID}
              RoleArn: !GetAtt TestEventBridgeIAMrole.Arn
  
    TestEventBridgeIAMrole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: {任意のロール名}
        AssumeRolePolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Principal:
                Service: events.amazonaws.com
              Action: sts:AssumeRole
  
    PutEventsDestinationBus:
      Type: AWS::IAM::Policy
      Properties:
        PolicyName: {任意のポリシー名}
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action:
                - events:PutEvents
              Resource: 
                - {送信先リージョンのイベントバスARN}
        Roles:
          - Ref: TestEventBridgeIAMrole
  

送信先リージョン(ap-northeast-1)のymlでは

  • イベントバス

の設定をします。

Resources:
  TestEventBus:
    Type: AWS::Events::EventBus
    Properties:
      Name: {任意のイベントバス名}

今回のように別リージョンのイベントをトリガーとしてlambdaを起動したい場合は、functionのeventsにeventBridgeを指定します。

functions:
  testFunction:
    handler: {handlerのパス}
    events:
      - eventBridge:
          eventBus: !Ref TestEventBus
          pattern:
            source:
              - {source}
            detail-type:
              - {detail-type}
            detail: 
              eventType: 
                - {eventType}

これで設定は完了です。{source}や{detail-type},{eventType}などはマネジメントコンソールで表示されるイベントパターンを参考にするとわかりやすいです

最後に

本当はap-northeast-1で全てのサービスが利用できるようになるのが一番なのですが、なかなか大変なのでしょう。AWS様には日頃からお世話になっておりますので、こちら側で対応できる部分はこちら側で対応するのが筋というものです。この記事がいつか誰かの役に立つことを願っております。ありがとうございました。

一覧に戻る