Amazon CloudFrontのパスパターンの設定にはデフォルトルートオブジェクトの考慮が必要

2023.10.06

初めに

CloudFrontでドメイン直下のパスを指定するパスパターンに関してうまく動作していなかった事象がドキュメント上に言及されておらず検証したところ個人的には感覚と一致しなかったので紹介します。

なお本記事で紹介する挙動についてはあくまで自分の検証結果に基づき確認された挙動でありドキュメントに明記されている仕様ではないという点はご注意ください。

やりたいこと

CloudFrontでパスパターンを設定しドメイン直下(/)にアクセスした場合にdefault(*)以外の指定したパスパターンにマッチさせ振り分けたい。

結論

ドメイン直下のアクセスを振り分ける場合パスパターンにはデフォルトルートオブジェクトのパスを含めて指定が必要。

検証用コンテンツ

確認のためにオリジンとしてS3とEC2(php artisan serveによる開発サーバ)を用意します。

S3バケットにはindex.htmlを用意しておきます。

EC2では/(ドメイン直下)、index.htmlindex.phpでアクセスされた場合にコンテンツを返すようにしておきます。

それ以外のパスでアクセスされた場合、S3側はAccessDenided、EC2側は404 NotFoundを返すようになってます(特別な設定をしているわけではなくコンテンツが存在しないだけ)。

検証1

デフォルトルートオブジェクト: index.html

ビヘイビアとしては以下の設定を行っています。記載としては省略しておりますがキャッシュポリシーはCachingDisabledにする等で今回の検証に直接影響が出ないようにしています。

優先順位 パスパターン オリジン
0 / S3バケット
1 default(*) EC2

この状態でドメイン直下に対してアクセスを行うとEC2側のコンテンツが返却されているため少なくともdefault(*)側のパスパターンが適用されたことがわかります。

ただこの時点ではあくまで/というパターンに一致していないだけで、ないとは思いますが/がなんらかエスケープされて解釈される等も考えられるためドメイン直下を指定する場合のパスパターンが適切でない可能性も考えられます。

検証2

デフォルトルートオブジェクト: なし(未指定)

優先順位 パスパターン オリジン
0 / EC2
1 default(*) S3バケット

デフォルトルートオブジェクトを未設定、パスパターンのオリジンを先ほどと逆にしてアクセスしてみます。

先ほどとは違い/側のパターンに当てていますが、この場合もEC2側のコンテンツが返却されます。

先に記載した通りEC2は/(ドメイン直下)、index.htmlindex.php以外にアクセスされた場合は404が返却され、かつ今回デフォルトルートオブジェクトは設定されていないためパスパターンとしてドメイン直下を指したい場合は/を指定するという形で間違いなさそうです。

では検証1の時でそちらのパターンが適用されなかったのはなぜでしょうか。

検証3

デフォルトルートオブジェクト: index.html

優先順位 パスパターン オリジン
0 /index.html S3バケット
1 default(*) EC2

この設定をしてドメイン直下にアクセスを行うとS3側のオブジェクトが返却されているためデフォルトルートオブジェクトが反映された後のパスがパスパターンのマッチングに使われていることがわかります.

終わりに

個人的な感覚としてデフォルトルートオブジェクトはあくまでディストリビューションからオリジンに対するリクエストに作用するもので振り分け判定等には作用しないと思っていたのですが、どうやらパスパターンのマッチングの前に評価されているようです。

直接言及されていないだけで色々な要素を複合すると遠回し的にこの現象が仕様と解釈できるような文言も見当たりませんでした。
あくまで今回の検証に基づき推定される動作ご理解いただき実際にご利用される際は動作確認の上設定いただけますと幸いです。