EventBridgeを使って2つのLambda関数を連携させる

目次

EventBridgeを使って2つのLambda関数を連携させる

EventBridgeはフルマネージドのイベントバスサービスです。

Amazon EventBridge は、コードを作成せずに、AWS のサービス、独自のアプリケーション、Software as a Service (SaaS) アプリケーションのデータの変更にリアルタイムにアクセスできるサービスです。Amazon EventBridge により、イベントがほぼリアルタイムで自動的に送信されます。

Amazon EventBridge のよくある質問

今回はEventBridgeを使用して、2つのLambda関数を連携させることを目標とします。

構築する環境

Diagram of integrating two Lambda functions using EventBridge.

2つのLambda関数を作成します。

1つ目のLambda関数でEventBridge向けにイベントを発行します。
具体的には、現在日時からUNIX時間を取得し、イベントにこれを含めて発行します。

EventBridgeでは、1つ目のLambda関数から受信したイベントに関するルールを定義します。
具体的には、Lambda関数2をターゲットとする内容のルールです。

2つ目のLambda関数では、受け取ったイベント内容に従って処理を行います。
具体的には、イベントから取得したUNIX時間が偶数/奇数か判定します。

関数のランタイムはPython3.8とします。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/099

テンプレートファイルのポイント解説

EventBridge

Resources:
  EventsRule:
    Type: AWS::Events::Rule
    Properties:
      EventBusName: !Ref EventBusName
      EventPattern:
        source:
          - !Ref Prefix
      Name: !Sub "${Prefix}-EventsRule"
      State: ENABLED
      Targets:
        - Arn: !Ref FunctionArn2
          Id: !Ref Function2
Code language: YAML (yaml)

EventBusNameプロパティにイベントバス名を指定します。

イベントバスとは、イベントを受信するパイプラインです。イベントバスに関連付けられたルールによって、受信したイベントが評価されます。

Amazon EventBridge イベントバス

今回はデフォルトのイベントバス「default」を使用します。

EventPatternプロパティで、本ルールで受け付けるイベントを指定します。

イベントパターンでは、ルールでマッチングするイベント構造とフィールドを定義します。

Amazon EventBridge ルール

今回はsourceの値が「fa-099」であるイベントを本ルールの対象とします。

Targetsプロパティで、本ルールにマッチしたイベントの送信先を指定します。

ターゲットとは、ルールに定義されたイベントパターンにイベントがマッチしたときに、EventBridge がイベントを送信する先のリソースまたはエンドポイントです。

Amazon EventBridge ターゲット

今回は後述するLambda関数2を指定します。

ターゲットにLambda関数を指定する場合、EventBridgeが関数を呼び出すという挙動になります。
そのためEventBridgeに関数を呼び出す権限を与える必要があります。

Resources:
  EventsRulePermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref Function2
      Action: lambda:InvokeFunction
      Principal: events.amazonaws.com
      SourceArn: !GetAtt EventsRule.Arn
Code language: YAML (yaml)

以下のAWS公式ページを参考に設定しました。

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-use-resource-based.html#eb-lambda-permissions

Lambda関数

関数1

Resources:
  Function1:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile: |
          import boto3
          import datetime
          import json
          import time
          import os

          event_bus_name = os.environ['EVENT_BUS_NAME']
          detail_type = os.environ['DETAIL_TYPE']
          source = os.environ['SOURCE']

          client = boto3.client('events')

          def lambda_handler(event, context):
            now = datetime.datetime.now()
            unix_time = int(time.mktime(now.timetuple()))

            detail = json.dumps(
              {
                'now': now.strftime('%Y-%m-%d %H:%M:%S.%f'),
                'unix_time': unix_time
              }
            )

            entry = {
              'Time': datetime.datetime.now(),
              'Source': source,
              'Resources': [],
              'DetailType': detail_type,
              'Detail': detail,
              'EventBusName': event_bus_name
            }
            print(entry)

            response = client.put_events(
              Entries=[entry,]
            )
            print(response)
      Environment:
        Variables:
          EVENT_BUS_NAME: default
          DETAIL_TYPE: unix-time-event
          SOURCE: !Ref Prefix
      FunctionName: !Sub "${Prefix}-function-01"
      Handler: !Ref Handler
      Runtime: !Ref Runtime
      Role: !GetAtt FunctionRole.Arn
Code language: YAML (yaml)

EventBridgeにイベントを発行する上で、特別な設定は不要です。
CloudFormationでLambda関数を作成する方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationでLambdaを作成する3パータン(S3/インライン/コンテナ) 【CloudFormationでLambdaを作成する】 CloudFormationでLambdaを作成する場合、大別すると以下の3パターンあります。 S3バケットにコードをアップロードする インライ...

今回はインラインで実行するコードを記載します。

関数で実行するコードの内容は以下の通りです。

  1. 現在日時からUNIX時間を取得する。
  2. EventBridge用クライアントオブジェクトのput_eventsメソッドを実行し、イベントを発行する。

put_eventsメソッドに渡す引数ですが、以下のAWS公式ページを参考に設定しました。

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/events.html#EventBridge.Client.put_events

具体的には、以下のようなイベントデータを作成し、発行します。

{
  'Detail': '{"now": "2022-11-22 23:28:26.622445", "unix_time": 1669159706}',
  'DetailType': 'unix-time-event',
  'EventBusName': 'default',
  'Resources': [],
  'Source': 'fa-099',
  'Time': datetime.datetime(2022, 11, 22, 23, 28, 26, 622526)
}
Code language: Python (python)

Detailに関数2に渡すデータを格納します。
形式はJSON文字列である必要があります。
今回は現在日時とそのUNIX時間を指定します。

EventBusNameにイベントバス名を指定します。
今回はデフォルトイベントバスを使用しますので、「default」を指定します。

Sourceの値はイベントソースを指定します。
今回はEventBridgeルールのイベントパターンで、この値をチェックするように設定しています。
ですから本パラメータは「fa-099」を指定します。

関数2

関数2の設定は、関数1と同様です。
こちらは実行するコードのみを確認します。

def lambda_handler(event, context):
  print(event)

  unix_time = event['detail']['unix_time']

  if (unix_time % 2) == 0:
    print('{int} is even !'.format(int=unix_time))
  else:
    print('{int} is odd !'.format(int=unix_time))
Code language: Python (python)

EventBridgeから受け取ったイベントからUNIX時間を取得し、偶数/奇数を判定します。
イベントデータはevent変数に格納されています。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • EventBridgeルール:fa-099-EventRule
  • Lambda関数1:fa-099-function-01
  • Lambda関数2:fa-099-function-02

作成されたリソースをAWS Management Consoleから確認します。
EventBridgeルールを確認します。

Detail of EventBridge 1.
Detail of EventBridge 2.

デフォルトイベントバスにルールが作成されています。
イベントパターンやターゲットを見ると、イベントデータのsourceの値が「fa-099」の場合、関数2にイベントデータを送信することがわかります。

一応、イベントルールの詳細設定も確認します。

Detail of EventBridge 3.
Detail of EventBridge 4.
Detail of EventBridge 5.

2つのLambda関数を確認します。

Detail of Lambda Function 1.
Detail of Lambda Function 2.

両関数ともに、CloudFormationテンプレートで指定した通りに作成されています。
関数2に注目すると、EventBridgeからの呼び出しが許可されていることもわかります。

動作確認

1回目

準備が整いましたので、関数1を実行します。

Detail of Lambda Function 3.

関数1のページから「Test」をクリックして実行します。

関数1の実行ログをCloudWatch Logsから確認します。

Detail of Lambda Function 4.

関数が正常に実行されたことがわかります。
イベント用オブジェクトが作成され、それが正常にEventBridgeに発行されたことが読み取れます。
今回のUNIX時間は「1669163606」でした。

続いて関数2のログを確認します。

Detail of Lambda Function 5.

関数が実行された形跡があります。
つまりイベントがEventBridgeに発行されたことによって、ルールで指定した関数2が自動的に呼び出されたということです。

detailで渡されたUNIX時間の偶数/奇数判定を行い、「1669163606 is even !」が出力されました。

2回目

もう一度、同じ操作を行います。

以下が両関数の実行ログです。

Detail of Lambda Function 6.
Detail of Lambda Function 7.

今度は関数1でUNIX時間「1669163697」を持つイベントがEventBridgeに発行されました。
これを受けて自動的に関数2が実行され、奇数と判定されて「1669163697 is odd !」が出力されました。

まとめ

EventBridgeを使用して、2つのLambda関数を連携させる方法を確認しました。

目次