ALBをLambdaの「顔」にする:同期・非同期の境界線と、現場でハマるJSON変換の罠
「ALBのターゲットグループにLambdaをぶら下げる」。一見、EC2やECSを配置するのと同じような感覚で設定してしまいがちですが、ここにはクラウドエンジニアなら必ず一度は通る「JSONペイロード変換」と「タイムアウト」という、特有の深淵が広がっています。
今日は、AWSにおけるALB(Application Load Balancer)とLambdaの統合について、教科書には載っていない「現場の肌感覚」を交えて深掘りしていきましょう。
—
1. なぜALBを「Lambdaの入り口」にするのか?
通常、Lambdaを叩くなら Invoke APIやAPI Gatewayを想像するでしょう。しかし、ALBを前段に置くことには明確なメリットがあります。
1. 既存インフラとの統合: 既にALBで運用しているドメイン配下に、特定のパス (/api/v2/* など) だけLambdaで処理させるといったルーティングが容易です。
2. セキュリティの統一: WAFをALBに紐付けるだけで、Lambdaへのリクエストも包括的に防御できます。
3. コスト効率: API Gatewayの「リクエストごとの課金」を回避し、ALBの固定料金+Lambdaの実行時間でコストを最適化できるケースが多いのです。
—
2. パケットの行方:HTTPからJSONへの「魔法の変換」
ALBにリクエストが届くと、ALBはHTTPリクエストを独自のJSON構造体に「翻訳」してLambdaに渡します。これが、開発者が最初に直面する壁です。
ALBが送るJSONの構造(抜粋)
{
"httpMethod": "GET",
"path": "/hello",
"queryStringParameters": { "id": "123" },
"headers": { "host": "example.com", "user-agent": "curl/7.68.0" },
"body": null,
"isBase64Encoded": false
}
ここで注意すべきは、body が文字列として渡される点です。JSONを送る場合、Lambda側で必ず json.loads(event['body']) を実行しなければなりません。逆に、Lambdaが返すレスポンスも「ALBが理解できるJSON」である必要があります。
LambdaからALBへのレスポンス形式
def lambda_handler(event, context):
# 必須のレスポンス構造
return {
"isBase64Encoded": False,
"statusCode": 200,
"statusDescription": "200 OK",
"headers": {
"Content-Type": "application/json"
},
"body": '{"message": "Hello from Lambda!"}' # ボディは必ず文字列にする
}
このフォーマットを崩すと、ALBは容赦なく 502 Bad Gateway を返します。デバッグ時は、CloudWatch Logsで event オブジェクトを一度全出力するのが鉄則です。
—
3. タイムアウトの「二重構造」に注意せよ
現場で最も多いトラブルが「ALBとLambdaのタイムアウトの不整合」です。
- ALBのアイドルタイムアウト: デフォルトは60秒。これを超えると
504 Gateway Timeout。 - Lambdaのタイムアウト: 関数設定で決まる(例: 30秒)。
鉄則:ALBのタイムアウト値 > Lambdaのタイムアウト値 に設定してください。
もしLambdaの実行時間がかかりそうな重い処理を行う場合、ALB側で設定を延ばす必要があります。しかし、クライアント(ブラウザやアプリ)側が待ちきれずにコネクションを切断すれば、バックエンドでLambdaが動き続けていても、ユーザーにはエラーが返ります。
Tips: 処理が重い場合は、Lambdaを同期的に呼び出すのではなく、SQSを挟んだ非同期パターンへの設計変更を検討する勇気を持ってください。
—
4. 実戦:curlで挙動を確認する
まずは単純なリクエストを投げて、疎通とレスポンス構造を確認しましょう。
# ヘッダーとレスポンスを詳細に確認する
curl -v -H "Content-Type: application/json" \
-X POST -d '{"name": "SRE"}' \
https://api.example.com/process
もし 502 が返ってくるなら、以下の3点を確認してください。
1. Lambdaの実行権限: elasticloadbalancing:Invoke の権限がLambdaのリソースベースポリシーにあるか?
2. ターゲットグループの登録: Lambdaが正しいターゲットグループに登録されているか?
3. レスポンスJSON: statusCode や headers キーが欠落していないか?
—
5. まとめ:シニアエンジニアからの助言
ALBとLambdaの統合は非常に強力ですが、API Gatewayのような「リクエスト/レスポンスの自動バリデーション機能」はありません。すべてはコード上の実装と、ALBの設定にかかっています。
- 同期か非同期か: クライアントがレスポンスを即座に必要としないなら、無理にALB経由で待たせず、直接Lambdaを非同期起動する方がシステム全体の堅牢性は高まります。
- オブザーバビリティ: X-Rayを有効にし、ALBからLambdaへトレースIDが引き継がれているかを確認しましょう。ボトルネックがネットワークにあるのか、Lambdaのコールドスタートにあるのかを可視化するのは、SREの第一歩です。
技術は常に進化しますが、パケットがどこで止まっているのかを想像する力は、どんなクラウド環境でも廃れることはありません。皆さんの構築が、トラブルのない安定したものになることを願っています。
コメント