🎉

APIGatewayの前段にCloudFront導入したときの引っかかりポイント紹介

に公開

はじめに

今回は、既存のAPIGatewayの前段にCloudFrontを導入した際の引っかかりポイントを紹介します。

作業の経緯としては、APIGatewayの費用を削減したいなーと思っていたところ、

  • APIGateway のリクエストが多くまたそのほとんどがキャッシュヒットだった
  • CloudFrontはリセールサービスを導入していてリクエスト料金無料だった

という状態だったため、前段にCloudFrontを置いてそれにキャッシュをさせることで、APIGatewayのリクエスト数(料金)を下げようと、計画しました。

その作業の際にいろいろ引っかかったのでそれを紹介します。

引っかかりポイント① APIキー

既存のAPIGatewayのAPIはAPIキーを有効化していました。
これを考慮せずにCloudFrontを前段に挟んでしまうとキーがAPIGatewayまで届きません。

これは、CloudFrontのビヘイビア設定でキャッシュキーに「x-api-key」ヘッダーを追加することで解決しました。

引っかかりポイント② ビヘイビアのパスパターン設定

当初、APIGatewayのリソース設定を踏襲してCloudFrontのビヘイビアを設定しましたがうまくいきませんでした。
原因はAPIGateway側のURLで、URLには/[ステージ名]を付ける必要がありました。(https://12345abcde.execute-api.ap-northeast-1.amazonaws.com/[ステージ名])

これは、オリジンのOrigin pathに/[ステージ名]を追加することで解決しました。

引っかかりポイント③ デフォルトのエンドポイント設定

APIGatewayのAPIの設定でデフォルトのエンドポイントを非アクティブにできます。
最初はこの設定を知らず、CloudFrontのオリジンではデフォルトのエンドポイントを設定することになるので、非アクティブ化されていたせいでうまく疎通できませんでした。

これはアクティブ化することで解決しました。
※設定変更後APIのデプロイをする必要がありました。

引っかかりポイント④ OPTIONSメソッドに注意

まずは結論から、今回各ビヘイビアにはOPTIONSメソッドを許可する必要がありました。

こちらの記事にある通りですが、JSからAPIをたたいているなどCORSがある場合、そのパスに対してのOPTIONSメソッドによるリクエストが発生する場合があります。
https://zenn.dev/tm35/articles/ad05d8605588bd

今回APIGateway側の設定では、すべてのパスに対してOPTIONSメソッドがあったわけではなく、デフォルトパスがOPTIONSになっていました。

その設定に従ってCloudFrontの設定をし、各ビヘイビアでOPTIONSを許可していなかったため、CORS事前チェックのリクエストがエラーを返しCORS許可がされない事態が発生しました。

引っかかりポイント⑤ カスタムドメインがある状態での切り替え

これはCloudFrontを新規作成する際に引っかかったポイントです。

APIGatewayでカスタムドメインを使用している場合、内部的にはそのドメインをCNAMEにしたCloudFrontが作成されています。
2つ以上のCloudFrontで同一CNAMEを設定できないため、カスタムドメインがある状態でCloudFrontのCNAMEに同一ドメインを設定できないという事態が発生しました。

これは無停止でCloudFront経由に切り替えたい場合に困りました。
が、いったんCloudFront側のCNAMEはワイルドカードドメインにし、切り替え後にカスタムドメインを削除→CNAMEをカスタムドメインだったものに切り替える流れで無停止切り替えを実現しました。(カスタムドメインがZoneApexの場合はこの方法をとれないのでよかった。。)

まとめ

最初からCloudFrontありきのAPIGatewayを設計していれば引っかからなそうなところでも、いま動いているものに対しての変更ということで少し苦労しました。

幸いにも本番と構成が同じ検証環境があったので、検証でいろいろ引っかかりながら設計し、本番ではトラブルなく進むことができました。

We're Hiring!

DELTAではチームの一員になっていただける仲間を募集中です!
下記フォームよりお気軽にご連絡ください!

https://docs.google.com/forms/d/e/1FAIpQLSfQuWNU1il5lq2rVdICM0tSK_jTsjqwc52LYEwUxBq7_ImtrQ/viewform

DELTAテックブログ

Discussion