🚀
ALB → Lambda → S3 でメンテナンスページを返す仕組みを試してみた
概要
今回は Application Load Balancer (ALB) から AWS Lambda を呼び出し、
さらに Amazon S3 に置いた静的 HTML を返す構成を試してみました。
通常は EC2 や ECS をターゲットにする ALB ですが、ターゲットタイプに Lambda を選べるため、
「メンテナンス中は Lambda 経由で固定の 503 ページを返す」といった使い方が可能になります。
構成イメージは以下の通りです。
- ALB: インターネット公開、HTTP 80 を受け付け
- Lambda: ALB から呼び出され、S3 から HTML を取得して返却
- S3: メンテナンスページ(例: 503.html)を配置
手順
1. S3 バケット作成
- コンソール → S3 → 「バケットを作成」
- バケット名は一意の名前(例:
alb-lambda-demo-xxxx
) - 作成後、
503.html
をアップロード
<html><body><h1>503 Service Unavailable</h1></body></html>
2. Lambda 実行ロールの作成
- IAM → ロール → 作成
- ユースケース: Lambda
- アタッチするポリシー
-
AWSLambdaBasicExecutionRole
(CloudWatch Logs 出力用) - S3 読み取り用のカスタムポリシー(
s3:GetObject
を対象バケットに許可)
-
3. Lambda 関数作成
- Lambda → 「関数を作成」
- ランタイム: Python 3.12 or 3.13
- 実行ロール: 上で作成したロールを指定
- コードを以下のように設定
import boto3
import os
def lambda_handler(event, context):
bucket_name = os.environ['BUCKET_NAME']
html_key = "503.html"
s3_client = boto3.client('s3')
response = s3_client.get_object(Bucket=bucket_name, Key=html_key)
html_content = response['Body'].read().decode('utf-8')
return {
"statusCode": 503,
"statusDescription": "503 Service Unavailable",
"headers": {
"Content-Type": "text/html"
},
"body": html_content,
"isBase64Encoded": False
}
- 環境変数
BUCKET_NAME
を設定 - タイムアウトを 30 秒に変更
4. ALB による呼び出し許可
- Lambda → 設定 → アクセス権限 → 「リソースベースポリシー」
- サービス
elasticloadbalancing.amazonaws.com
にlambda:InvokeFunction
を許可する権限を追加
5. ターゲットグループ作成
- EC2 → ターゲットグループ → 作成
- ターゲットタイプ: Lambda
- Lambda 関数を指定
6. ALB 作成
- EC2 → ロードバランサー → 作成
- 種類: アプリケーションロードバランサー
- スキーム: インターネット向け
- リスナー: HTTP 80
- デフォルトターゲットグループ: 上で作成した Lambda タイプ TG
7. 動作確認
- ALB の DNS 名にアクセス
- ブラウザに
503.html
の内容が返れば成功
まとめ
- ALB のターゲットとして Lambda を利用できるため、メンテナンスページの切り替えなどに有効
- CloudWatch Logs を見ると Lambda 実行状況を確認できる
- 表示されない場合は以下を要チェック
- ALB の SG が HTTP を公開しているか
- ALB のリスナー設定が正しいか
- Lambda のレスポンス形式(
Content-Type
の書式など) - Lambda に ALB 呼び出し許可を付与しているか
- CloudWatchからLambdaのログイベント確認
Discussion