
こんにちは。株式会社フーリエ・メンテナンスマニアの市川です。
ひと昔前には、「.htaccessでメンテナンス切り替えすればいいよね」だった雰囲気が、いまは WAF など上位層で捌きましょうといったリソースエコな流れを感じている今日この頃。
今回は、アプリケーション到達前の AWS WAF や ALB で分岐してエコなメンテナンス表示の実現について紹介します。
方法1. AWS WAFを利用する
まずは、WAFから! WAFは「 Amazon CloudFront 」「 Application Load Balancer (ALB) 」 「 Amazon API Gateway 」に適用できるサービスです。今回は、S3に静的コンテンツを配置して CloudFront 経由で配信されてる想定で、WAFを使ったメンテナンス切り替え手順を紹介します。
AWSマネージメントコンソールの「 WAF & Shield 」で操作していきます。
1) 許可するIPを設定
動作検証をするため特定のIPは許可するよう設定してあげます。
(グローバルリージョンで!)
WAF & Shield > IP sets から 「 Create IP set 」
を選択します。

設定画面を開いたら各項目を入力していきます。

IP set name
は識別しやすい名付けで自由に設定できます。今回は、メンテナンス時に許可するIPアドレスなので、そのまま maintenanceAllowIP
としました。 許可するIPは、 xxx.xxx.xxx.xxx/32
のようにCIDR表記で記載します。 複数設定する場合は改行して追加します。 ちなみに自分のグローバルIPアドレスは こちらのサイト などで確認できます。
入力が終わったら、 [ Create IP set ]
を押してください。
2) Web ACLsを設定
ここからメンテナンスページの表示設定をしていきます。(グローバルリージョンで!)
メンテナンスページを表示させるリソース、許可するIP、レスポンスの内容等を設定します
WAF & Shield > Web ACLs から 「Create web ACL」
を選択します。

設定画面を開いたら各項目を入力していきます。

Name
は識別しやすい名付けで自由に設定できます。今回は maintenance
としました。
Resource Type
は CloudFront にメンテナンスページの設定をするので、 CloudFront distributions
にチェックを入れてます。
入力を終えたら [Next] を押し、ルールを設定に進みます。

先程、設定したルールを適用します。 IP set
に maintenanceAllowIP
を選択し、 Source IP address
と Allow
にチェックを入れて[Add rule]を押して次へ進みます。

許可するIP以外はアクセスできないようにするので Default action
は Block
にします。
 Custom response
から、ステータスコードを503に指定し、メンテナンス時に表示するhtmlを設定します。
設定ができたら[Next]を押して進みます、確認画面が表示されますので、内容を確認して[Create Web ACL]を押してください。これで、ACL設定は完了です。
3)メンテナンス実施
いよいよ、メンテナンスページの表示になります。
 WAF & Shield > Web ACLs から 設定した「maintenance」
を選択します。
次に、先で設定した maintenance
から Associated AWS resources
のタブを選択し、 Add AWS resources
を押してください。

メンテナンスページを表示する CloudFront を選択しましょう。
[Add]を押すことでメンテナンスページの表示が完了します。

4)メンテナンス解除
WAF & Shield > Web ACLs から 設定した「maintenance」
を選択します。

Associated AWS resources
タブから外したいリソースを選択し、[Disassocite] をクリックしてください。

ポップアップが表示されるので、フォーム内に remove
と入力し [Disassocite] を押すとWAFを外すことができます。
若干手順が多く、面倒ですが一度ACLを作成すれば、メンテナンス時にWAFのACL設定を 当てる/外す
だけでいいので、用意しておくといいかなと思います。
方法2. ALBのリスナールールを利用する
WAF 使わずに ALB のリスナールールを利用して実現することもできます。 EC2でアプリケーションを運用する際に、1台構成でも ELB/ALB を介している場合が多いと思いますので、今回は、ALB+EC2構成を想定して解説します。 ※ この利点はこちらの記事参照 => 「 1台のEC2でもELBを使うメリットについてまとめてみました 」
AWSマネージメントコンソールの「 EC2 」で操作していきます。
1)ルールの編集画面へ
EC2 > ロードバランサー > 対象となるALB
を選択します。次に、リスナーのタブを選択してルールの編集を押してください。

2)許可するIP設定

許可するIPアドレスをCIDR表記 = xxx.xxx.xxx.xxx/32
で記載します。
IPの設定ができたら転送先となるターゲットグループを選択してください。
設定が済んだら[保存]を押してください。
3 )メンテナンス設定&実施
上記で許可したIPアドレス以外は、メンテナンスページを表示するよう設定していきます。

今回は、「メンテナンス中です」とテキストが返るだけの味気ない設定ですが、htmlとかjson等も設定できます!
[更新] を押して設定完了となります。その時点でメンテナンス状態になります。
3)メンテナンス解除
上記のルールを元に戻すことで、メンテナンス解除になります。
WAF での設定と比較するとすごく楽ですが、メンテナンス状態から設定を戻すときに、WAFはACLを外すだけでしたが、こちらの方法はルーティング先を間違える可能性があるため作業に注意が必要です。
参考)Laravelでの方法
Laravel はアプリケーションによる対処になりますので本題とは外れますが、サーバに触れられない状況下でメンテナンスする場合もあると思います。 参考までに Laravel での対処法も紹介します。
Laravel にはメンテナンスモードが標準機能として用意されているのでコマンド一つで設定できます。
メンテナンスモードにすることで503レスポンスを返します。またmiddlewareで許可するIPの設定やbladeファイルを用意することでメンテナンスページのカスタマイズができます。
メンテナンスモード切り替え
以下、artisanコマンドでメンテナンスモードの切り替えができます。
// メンテナンスモード実行
php artisan down

// メンテナンスモード解除
php artisan up
とっても簡単ですね!
middlewareで許可するIPを設定する場合、 .env
でIPリストを管理するとよいかと思います。
許可するIPを変更したいときに毎回デプロイするのは面倒なので笑
あと、一点注意すべきところは、メンテナンスモードでも composer update
の実行中にはライブラリが読み込めなくなり500エラーが発生します。 わずかな時間かと思いますがそれすら許されない場合もあると思いますので気をつけてください。
さいごに
今回は、AWS WAF・ALB・Laravelでのメンテナンスページの表示について紹介しました。サイト・システムによって構成は変わってくると思うので、要件にあったやり方を選択してください。
それではまた次の記事で!!