Google Cloud 上で動く Web サービスを Cloud Armor + Cloud Storage でメンテナンス画面へ切り替える方法
AWS でロードバランサー + EC2 等で構成された Web サービスの場合、一時的にメンテナンス画面へ切り替えるには
- ロードバランサーのリスナー設定で、固定レスポンス(HTMLで構成。このHTMLをメンテナンス画面の内容にする)を返すリスナーを新しく追加する(優先度は一番下にする)
- メンテナンス切り替え時、1.のリスナーの優先度を最上にする
- メンテナンスをスルーする許可IPを登録する
ことで、簡易的にメンテナンス画面用のHTMLを返すことができました。弊社ではパブリッククラウドを AWS から Google Cloud へ移行した際、AWS 時に構築していた上記メンテナンス切り替え機構をどのようにして Google Cloud 上で実現する方法を調査した結果、類似の構成を作ることができました。今回はその実例を紹介いたします。
採用した構成: ロードバランサー + Cloud Armor + Cloud Storage
先に結論から書きますと、ブラウザから Web サービスへのリクエストをバイパスするロードバランサーのバックエンド サービスに対し、Cloud Armor と Cloud Storage を介在させることでメンテナンス画面を切り替えできる構成を採用しました。この構成のメリットは
- Cloud Armor ポリシーに予め設定したバックエンド セキュリティ ポリシーのメンテナンス用ルールの priority を変更するだけで、メンテナンス画面を切り替えることができる
- Cloud Armor ポリシーの設定で IP アドレスによるアクセス制御が可能
- メンテナンス画面の HTML は Cloud Storage に配置するだけで良い
があります。逆にデメリットとして考えられたのが
- URL のリライトに対応しておらず、ステータスコード302のリダイレクトのみ設定可能
である点でした。これに関しては検討の結果、SEO への悪影響は無いであろうという判断に至りました。301ですと恒久的なリダイレクトとなるため問題がありますが、302は一時的なリダイレクトとなるためメンテナンス画面を表示させる分には問題ないと判断した次第です。
採用を見送った構成: ロードバランサー pathMatcher + Cloud Storage
こちらは Cloud Armor を使用せず、ロードバランサーの pathMatcher で直接 Cloud Storage のメンテナンス画面へのリクエストを切り替える構成案です。この構成のメリットは
- Cloud Armor を介さずロードバランサーのルーティングルールでメンテナンス画面を切り替えるため、インフラ構成がシンプル
- ロードバランサーの pathPrefixRewrite を使うことで URL のリライトを行うことが可能(ステータスコードは307が選択可能)
- メンテナンス画面の HTML は Cloud Storage に配置するだけで良い
があります。デメリットとしては
- IP アドレスによるアクセス制御ができないため、社内のみメンテナンス画面を非表示にすることができない
- pathPrefixRewrite はマッチした全てのパスを Cloud Storage バケットに配置した単一のメンテナンス用 index.html へプロキシすることができない
がありました。最終的にデメリット2.の影響が大きかったため、今回は採用しないことにしました。
Terraform にて Cloud Armor でメンテナンス画面に切り替える構成例
メンテナンス画面へ切り替えるための Cloud Armor ポリシーの Terraform 例を以下に示します。
resource "google_compute_security_policy" "default" {
name = "security-policy-for-maintenance"
type = "CLOUD_ARMOR"
description = "ロードバランサ用の Cloud Armor ポリシー"
dynamic "rule" {
content {
action = "allow"
description = "allowed_users"
match {
config {
src_ip_ranges = [
# ここに許可する IP アドレスを記述する
]
}
versioned_expr = "SRC_IPS_V1"
}
priority = 0
}
}
dynamic "rule" {
content {
action = "redirect"
description = "redirect_to_maintenance_page"
match {
config {
src_ip_ranges = ["*"]
}
versioned_expr = "SRC_IPS_V1"
}
priority = 1
redirect_options {
target = "https://storage.googleapis.com/{Cloud Storage のバケット名}/index.html"
type = "EXTERNAL_302"
}
}
}
}
この設定をメンテナンス画面切り替え時に terraform apply することで、メンテナンス画面を切り替えることができます。既にCloud Armor ポリシーに別のルールを設定している場合、それらのルールの priority を予め大きめの値(1000など)に設定しておくことで、メンテナンス画面切り替え時に既存のルールの priority を変更せずにメンテナンス画面ルールを最上位にすることができます。
終わりに
この構成を採用したのは2024年1月ですが、Google Cloud の機能改善速度は速いため、当初デメリットとしていたことがもしかしたら現在は解消されているかもしれません。今後も Google Cloud の機能改善を注視し、より良い構成を模索していきたいと考えています。