🔐

シングルページアプリケーション(SPA)のメンテナンスモードをAkamaiで実現した話

に公開

お久しぶりです。Join 1周年を迎えたイオンスマートテクノロジー株式会社(AST)SREチームのbutadoraです。

今回はとあるシングルページアプリケーション(SPA)にメンテナンスモードを提供するにあたり、少し試行錯誤したので書いておこうと思います。

3行まとめ

  • Akamai Propertyを使って、Originより手前でレスポンスを返すことでメンテナンスモードを実装
  • サイト本体は307リダイレクトでメンテページへ、REST APIは503エラーでJSONを返却
  • メンテモード入りのPropertyのバージョンをProductionのみに適用することで、Stagingをメンテナンス明け前の事前動作確認に利用

背景

  • SPAなサービスを、メンテナンスモードの状態でリリースしたいという相談があった
  • SPAはサイト本体とAPI、それぞれサブドメインが切られているような構成
    • サイト本体: web.example.com, API: api.example.com のようなドメイン構成
  • 各ドメインそれぞれの前段にAkamaiがいて、プロパティもそれぞれ存在している状況
  • 加えて、メンテ中にも開発メンバーはアクセスできる状態にしたいという制約があったためAkamai側で実現する方法を考えた

実際に設定したプロパティ

今回は具体的な挙動となる、 behaviors のみ記載します

サイト本体

{
    "behaviors": [
        {
            "name": "cacheRedirect",
            "options": {
                "enabled": "false"
            }
        },
        {
            "name": "redirect",
            "options": {
                "mobileDefaultChoice": "DEFAULT",
                "destinationProtocol": "SAME_AS_REQUEST",
                "destinationHostname": "SAME_AS_REQUEST",
                "destinationPath": "OTHER",
                "queryString": "APPEND",
                "responseCode": 307,
                "destinationPathOther": "/maintenance.html"
            }
        }
    ]
}
  • 同一ドメインの /maintenance.html に配置されている、静的なメンテナンスページへリダイレクト
  • 新たにアクセスしてきたユーザはこれによってメンテナンスページに遷移します
  • リダイレクトはキャッシュして欲しくないので cacheRedirect は明示的にdisable

REST API

{
    "behaviors": [
        {
            "name": "constructResponse",
            "options": {
                "enabled": true,
                "responseCode": 503,
                "forceEviction": true,
                "ignorePurge": true,
                "body": "{\"message\": \"in maintenance\"}"
            }
        },
        {
            "name": "modifyOutgoingResponseHeader",
            "options": {
                "action": "MODIFY",
                "standardModifyHeaderName": "CONTENT_TYPE",
                "newHeaderValue": "application/json",
                "avoidDuplicateHeaders": true
            }
        }
    ]
}
  • constructResponse で固定のbodyを返却
  • constructResponse は本来HTMLを返すためのものなので、Content-Typeヘッダーを上書きする
  • 既存アクセスユーザからのアクセスも届かなくなります。
  • リダイレクトはキャッシュして欲しくないので forceEviction は有効化

メンテナンス中の事前確認

  • 当初開発メンバーと会話していくつか案が浮かんだが、今回の要件には合わなかった
    • 社内VPNからのリクエストはアクセス許可 →開発者以外のメンバーが叩けるのはNG
    • クッキー(リクエストヘッダー)にパスワードがセットされていたらアクセス許可 →SPAから叩かれるAPIがクッキーを渡さないのでNG
  • そんな中で、「AkamaiのStaging環境のバージョンをメンテナンスモードのバージョンにしなければ良いのでは?」ととあるメンバーが提案
    • Akamai Stagingは本来本番展開前に確認するための環境で、hosts等でIPを直接指定するなどすれば、本番と同じ振る舞いをしてくれる
    • 本来の使い方ではないが、目から鱗だった
  • そのメンバーに感謝しつつ、Stagingのアクティベートをスキップするだけで、簡単に実現できた 🎉

最後に

  • 今回はアプリケーションの前段を閉塞してメンテナンスモードにする手段として、Akamaiを活用しました
  • 私はASTで初めてAkamaiを触るので、他にもっといい方法やNGな使い方があればコメントいただけると助かります!🙏
  • メンテナンスモードのON/OFFを切り替える仕組みはリファクタリング中なので、別の機会に🙋
GitHubで編集を提案
AEON TECH HUB

Discussion