S3 + CloudFront でホスティングしている静的 Web サイトをメンテナンス状態にする
はじめに
AWS S3 を用いてホストしている Web サイトで任意の期間だけメンテナンス画面を表示したいという要件がありました。
構成としては、前段に CloudFront をかましていているだけのシンプルな構成です。
細かい設定としては、S3 オリジンは静的 Web サイトホスティングを有効にし、CloudFront からのアクセスしか受け付けないように設定しています。
この記事では、上記の構成でどうやってメンテナンス画面を実現するかということをメインに考えていきます。
やりたいこと
実現するにあたりメンテナンス時の要件を整理してみます。
- 一般ユーザが Web サイトにアクセスするとメンテナンス画面を表示させたい。
- 管理者や開発者など特定の IP アドレスによるアクセスは許可し、通常通り操作できるようにしたい。
どうやって実現するか
結論から言うと、CloudFront に WAF の Web ACL を設定してアクセス制限する方法を取りました。
少し噛み砕いて、流れに沿って説明します。
Step1. Web ACL を作成
事前に WAF の設定をしておきます。WAF は、コンテンツへのアクセス制御や CloudFront に送られるリクエストの制御などができるファイアーウォールです。今回は、この WAF を使って Web ACL を作成し、CloudFront にアタッチします。
IP Sets
事前に許可したい IP アドレスのリストを作成しておきます。
マネジメントコンソールにログインし、こちら から作成します。CloudFront で使用するのでリージョンを Global(CloudFront) にする必要があります。
また、複数の IP アドレスを登録したい場合は、改行して 1 行毎に入力しておくことで設定できます。
Web ACLs
続いて Web ACL を作成していきます。こちら から作成します。こちらも同様にリージョンを Global(CloudFront) にし、ルールの追加の際に先ほど作成した IP Set を指定します。
下記のように Add my own rules and rule groups
を選び、Rule Type を IP Set にすると先ほど作成した、IP Set が出てくるのでそれを選択します。
Step2. S3 バケットにコンテンツを用意
ホスティングしている S3 バケットにメンテナンス時に表示したいコンテンツを追加します。
今回は、画面にメンテナンスの時間を表示させたかったのでローカルで HTML を編集してそのまま S3 バケットにコピーしました。コピーは AWS CLI によって行ないました。
aws s3 cp ./src/maintenance.html s3://<bucket name>/dist/maintenance.html --acl public-read
ここでは全てのユーザへの読み取り権限を許可するため、--acl
オプションを使って公開設定にしました。
Step3. CloudFront に WAF を適用
ここまできたら CloudFront 側の設定をしていきます。
まずは、Distribution に上記で作成した Web ACL をアタッチします。
最後にカスタムエラーレスポンスを設定します。
ステータスコードが 403 だった場合、メンテナンス画面として表示したいコンテンツのパスと返却するステータスコードを 503 と設定しました。
高いオペレーショナルエクセレンスを目指して
長くなってしまいましたが、ここまでくると最初に述べた要件を満たした上でメンテナンス状態を作ることができました。とは言え、メンテナンスの度にこのフローを実行するとかなり時間がかかりそうですし、何より手作業によるミスが発生しそうです。
今後の課題としては、今回のプロセスをコード化して運用効率を高めていきたいです。
余談ですが、AWS の Well Architected フレームワークにも「運用上の優位性」という柱があります。業務プロセスの継続的な改善や自動化はかなり重要なトピックとされています。詳しくは下記のクラスメソッドさんの記事が非常に参考になったので、気になった方は是非ご一読ください。
まとめ
今回は S3 + CloudFront 環境下におけるメンテナンス画面への切り替え方法を考えてみました。最後にポイントをまとめました。
- WAF の Web ACL によってアクセス制限をする。
- Web ACL には IP Set のルールを使うと IP によって制限をかけることができる。
- オペレーションコストがかかりそうなことは積極的に改善と自動化を。
ここまで読んでくださりありがとうございます。
他にも「こういった方法があるよ」「こっちが楽にできるよ」などありましたらコメント、GitHub どちらでも構いませんので、ご教授いただけると幸いです。
参考にさせていただいたサイト
Discussion