ALB の固定レスポンスでメンテナンス画面を仕込み、ルールの優先度入れ替えだけで切り替える
nginx の rewrite などでメンテナンス画面を出していたのを、ALB のリスナールールだけで済ませる方法。ルールは普段から作っておき、メンテナンス時は優先度を入れ替えるだけにする。
構成(3 つのルール)
| ルール | 条件 | アクション | 通常時の優先度 | メンテ中 |
|---|---|---|---|---|
| Forward | path * | ターゲットグループへ転送 | 1 | 101 |
| Maintenance Bypass | 送信元 IP(管理者の IP) | ターゲットグループへ転送 | 101 | 1 |
| Maintenance | path * | 固定レスポンス(503 + HTML) | 102 | 2 |
Bypass を入れておくと、メンテナンス中も管理者だけは本体にアクセスして動作確認できる。IP の代わりに特定の HTTP ヘッダーを条件にしてもよい。
Terraform(要点)
hcl
resource "aws_lb_listener_rule" "maintenance" {
listener_arn = aws_lb_listener.main.arn
priority = 102
condition {
path_pattern { values = ["*"] }
}
action {
type = "fixed-response"
fixed_response {
content_type = "text/html"
message_body = file("maintenance.html")
status_code = "503"
}
}
}Forward(priority 1、forward)と Bypass(priority 101、source_ip 条件で forward)も同じ aws_lb_listener_rule で作る。
切り替え(AWS CLI)
bash
# メンテナンス ON
aws elbv2 set-rule-priorities --rule-priorities \
RuleArn=$BYPASS,Priority=1 RuleArn=$MAINTENANCE,Priority=2 RuleArn=$FORWARD,Priority=101
# メンテナンス OFF
aws elbv2 set-rule-priorities --rule-priorities \
RuleArn=$FORWARD,Priority=1 RuleArn=$BYPASS,Priority=101 RuleArn=$MAINTENANCE,Priority=102set-rule-priorities は複数ルールの優先度をまとめて変えられるので、途中の中途半端な状態を作らずに済む。
注意点
- 固定レスポンスの本文にはサイズ上限がある(1024 文字程度)。画像や CSS は外部(S3 / CloudFront など)に置くか、インラインで小さく書く
- CLI で優先度を変えると Terraform の state とずれる。Terraform 側で
lifecycle { ignore_changes = [priority] }を付けるか、切り替えも Terraform 変数で行うかを決めておく - 503 を返すので、監視の外形チェックやヘルスチェック系のアラートはメンテ中に抑止しておく