AWS ALB + Lambdaでメンテナンスページを作る
概要
- AWS ALBにEC2やFargateなどをぶら下げてサービスを稼働させていて、時々メンテナンス作業のためにサービスを停止し、代わりにメンテナンスページを表示させるようにしたいときがある
- ここではALB+Lambdaに切り替えることを想定してメンテナンスページを表示させてみた
別解:ALB単独でメンテナンスページを表示させる場合
- Lambdaを使わずともALB単独で簡単なメンテナンスページを表示させることも可能である
- 下記のようにALBのリスナールールの設定で固定レスポンスを返す設定を使えばALB単独でメンテナンスページを表示させることは可能だ
- しかし、この方法には制約がある
- レスポンス本文は最大1024文字が上限
- HTTPレスポンスヘッダーはカスタマイズできない
- 画像などで別ファイルを使うには別サーバーを使う必要がある
構成
- 通常はALBとEC2やFargateを紐付けてサービスを運用しているが、メンテナンス時はEC2やFargateを切り離して、代わりにLambdaをALBに紐づける
- このときLambdaはVPCの中に置く必要はないが、同じリージョン内に設置する
手順
- Lambda関数を作成する
- HTMLファイルと画像ファイルをLambdaにアップロードする
- Lambda関数のコードを作成・テストする
- ターゲットグループを作成し、Lambda関数を加える
- ALBのリスナールールを設定して、LambdaとALBを紐づける
- 実際にアクセスして動作を確認する
手順1: Lambda関数を作成する
何も特別なことは必要ないので空のLambda関数を作成する
ここではランタイムをnode.js 14.xとしているが、他のものでも良い
IAM権限なども最小限以外は必要ない
手順2: HTMLファイルと画像ファイルをLambdaにアップロードする
ここではHTMLファイル1つとSVGの画像ファイルを1つ用意した
HTMLファイルの中で画像を呼び出すパスは「/image」としている
この2つをzipファイルに固めて、Lambdaにアップロードする
<html>
<head>
<meta charset="utf-8">
<title>メンテナンス</title>
</head>
<body>
<h1>メンテナンス中</h1>
<img src='/image'>
</body>
</html>
手順3: Lambda関数のコードを作成・テストする
index.jsのコードを作成する
あまり難しい処理はなく、HTTPリクエストのパスが「/image」なら画像ファイルを返し、それ以外ならHTMLファイルを返す
const fs = require('fs');
const html = 'ma.html';
const img = 'gnu-head.svg';
exports.handler = async (event) => {
// 画像を返す
if (event.path == '/image') {
var response = {
statusCode: 200,
statusDescription: '200 OK',
isBase64Encoded: false,
headers: {
'Content-Type': 'image/svg+xml',
'Cache-Control': 'no-store',
}
};
response.body = fs.readFileSync(img, 'utf8');
} else {
// HTMLを返す
response = {
statusCode: 503,
statusDescription: '503 Service Unavailable',
isBase64Encoded: false,
headers: {
'Content-Type': 'text/html; Charset=UTF-8',
'Cache-Control': 'no-store',
}
};
response.body = fs.readFileSync(html, 'utf8');
}
return response;
};
ALBから渡されるデータはだいたい次のようになっている
{
"requestContext": {
"elb": {
"targetGroupArn": "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a"
}
},
"httpMethod": "GET",
"path": "/lambda",
"queryStringParameters": {
"query": "1234ABCD"
},
"headers": {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"accept-encoding": "gzip",
"accept-language": "en-US,en;q=0.9",
"connection": "keep-alive",
"host": "lambda-alb-123578498.us-east-2.elb.amazonaws.com",
"upgrade-insecure-requests": "1",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
"x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476",
"x-forwarded-for": "72.12.164.125",
"x-forwarded-port": "80",
"x-forwarded-proto": "http",
"x-imforwards": "20"
},
"body": "",
"isBase64Encoded": false
}
引用元:https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/services-alb.html
手順4: ターゲットグループを作成し、Lambda関数を加える
AWSコンソールなどでALBに紐づけるためのターゲットグループを作成し
前項までで作成したLambda関数をグループに加える
手順5: ALBのリスナールールを設定して、LambdaとALBを紐づける
- EC2やFargateなどと同じような感じで、前項で作成したターゲットグループをALBに紐づける
- ヘルスチェックをすると503を返して失敗してしまうしLambda実行コストが無駄なのでヘルスチェックはしない
手順6: 実際にアクセスして動作を確認する
ブラウザでアクセスしてみてHTMLと画像が表示されることを確認する
Author And Source
この問題について(AWS ALB + Lambdaでメンテナンスページを作る), 我々は、より多くの情報をここで見つけました https://qiita.com/httpd443/items/f9251b0cf695731c21c6著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .