EventBridgeを使って2つのLambda関数を連携させる
EventBridgeはフルマネージドのイベントバスサービスです。
Amazon EventBridge は、コードを作成せずに、AWS のサービス、独自のアプリケーション、Software as a Service (SaaS) アプリケーションのデータの変更にリアルタイムにアクセスできるサービスです。Amazon EventBridge により、イベントがほぼリアルタイムで自動的に送信されます。
Amazon EventBridge のよくある質問
今回はEventBridgeを使用して、2つのLambda関数を連携させることを目標とします。
構築する環境
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公式ページを参考に設定しました。
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関数を作成する方法については、以下のページをご確認ください。
今回はインラインで実行するコードを記載します。
関数で実行するコードの内容は以下の通りです。
- 現在日時からUNIX時間を取得する。
- EventBridge用クライアントオブジェクトのput_eventsメソッドを実行し、イベントを発行する。
put_eventsメソッドに渡す引数ですが、以下のAWS公式ページを参考に設定しました。
具体的には、以下のようなイベントデータを作成し、発行します。
{
'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スタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- EventBridgeルール:fa-099-EventRule
- Lambda関数1:fa-099-function-01
- Lambda関数2:fa-099-function-02
作成されたリソースをAWS Management Consoleから確認します。
EventBridgeルールを確認します。
デフォルトイベントバスにルールが作成されています。
イベントパターンやターゲットを見ると、イベントデータのsourceの値が「fa-099」の場合、関数2にイベントデータを送信することがわかります。
一応、イベントルールの詳細設定も確認します。
2つのLambda関数を確認します。
両関数ともに、CloudFormationテンプレートで指定した通りに作成されています。
関数2に注目すると、EventBridgeからの呼び出しが許可されていることもわかります。
動作確認
1回目
準備が整いましたので、関数1を実行します。
関数1のページから「Test」をクリックして実行します。
関数1の実行ログをCloudWatch Logsから確認します。
関数が正常に実行されたことがわかります。
イベント用オブジェクトが作成され、それが正常にEventBridgeに発行されたことが読み取れます。
今回のUNIX時間は「1669163606」でした。
続いて関数2のログを確認します。
関数が実行された形跡があります。
つまりイベントがEventBridgeに発行されたことによって、ルールで指定した関数2が自動的に呼び出されたということです。
detailで渡されたUNIX時間の偶数/奇数判定を行い、「1669163606 is even !」が出力されました。
2回目
もう一度、同じ操作を行います。
以下が両関数の実行ログです。
今度は関数1でUNIX時間「1669163697」を持つイベントがEventBridgeに発行されました。
これを受けて自動的に関数2が実行され、奇数と判定されて「1669163697 is odd !」が出力されました。
まとめ
EventBridgeを使用して、2つのLambda関数を連携させる方法を確認しました。