EventBridge から Lambda を変数付きで実行する

概要
Lambda と API Gateway を組み合わせてアプリケーションのバックエンドを構築する機会が増えてきたが、この Lambda を EventBridge (旧 CloudWatch Event) と組み合わせることで、API としてだけでなくバッチ処理としても利用できるようにしてみた。
例えば、Lambda の裏にあるデータベースに対して定期的に SQL を実行したい場合があり、以前はそのためだけに別の Lambda を作成していたが、同じ Lambda を再利用できれば効率的と思い今回の検討に至った。
Lambda
API Gateway (HTTP API) で定義した複数のルートを全て 1 つの Lambda に結合して、その Lambda の中でパス毎に処理を振り分けるパターンを考える。
def handler(event, context):
if event['routeKey'] == "GET /api/path1":
...
elif event['routeKey'] == "POST /api/path2":
...
elif event['routeKey'] == "GET /api/path3":
...
API Gateway を経由した場合は、変数 event['routeKey']
にリクエストメソッド(GET, POST など)と、パスが組み合わされた文字列が入ってくるので、これでルーティング処理が可能である。
EventBridge
ここで、上記のルーティングのパスの 1 つとして定義した、 POST /api/path2
と同じ処理を EventBridge からも実行する場合を考える。
通常、EventBridge から Lambda を実行する場合、Lambda の変数 event は空であるが、EventBridge のターゲット入力の設定を追加することで、event に任意の変数を渡すことが可能となる。
設定で「定数 (JSON テキスト)」を選択し、以下を追加する。
{
"routeKey": "POST /api/path2"
}
Terraform
Terraform で書く場合、 aws_cloudwatch_event_target
に input
を追加する。
data "aws_lambda_function" "this" {
function_name = [Lambda関数名]
}
resource "aws_cloudwatch_event_rule" "this" {
name = [ルール名]
schedule_expression = "cron(0 0 * * ? *)"
}
resource "aws_cloudwatch_event_target" "this" {
rule = aws_cloudwatch_event_rule.this.name
arn = data.aws_lambda_function.this.arn
input = jsonencode({
routeKey = "POST /api/path2" # ← ここを追加
})
}
resource "aws_lambda_permission" "this" {
action = "lambda:InvokeFunction"
function_name = data.aws_lambda_function.this.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.this.arn
}