S3 と Cloudfront で静的ページ配信をしようとしたけど 307 リダイレクトが返ってきてしまう件

静的なウェブページを S3 に設置し、それを Cloudfront 経由で配信しようとした際に遭遇したトラブルです。

解決法

結論を書いてしまうと、1 時間ぐらい待っていると勝手に直ります。

現象

S3 にウェブページを設置、そして Cloudfront の Distribution を作成、Origin に先ほどの S3 を指定し、 楽勝楽勝と Create ボタンを押すところまでは順調だったのですが、その後、動作確認のために Cloudfront のエンドポイントにアクセスすると、なぜか Origin に指定した S3 の URL にリダイレクトされて困りました。 (しかも S3 には直接アクセスできないようにしていたので、Permission Denied がでる。)

期待していたのは、リダイレクトではなく、Origin に設置したコンテンツが Cloudfront から返ってくることでした。

Chrome のインスペクタなんかで確認すると、 どうやら Cloudfront からは 307 (Temporary Redirect) という見慣れない Status Code が返ってきていることが わかりました。

原因

↓の記事の回答にまんま答えが書いてあったのですが、

stackoverflow.com

All buckets have at least two REST endpoint hostnames. In eu-west-1, 
they are example-bucket.s3-eu-west-1.amazonaws.com and example-bucket.s3.amazonaws.com. 
The first one will be immediately valid when the bucket is created. 
The second one -- sometimes referred to as the "global endpoint" 
-- which is the one CloudFront uses -- will not, unless the bucket is in us-east-1. 
Over a period of seconds to minutes, variable by location and other factors, 
it becomes globally accessible as well. Before that, the 307 redirect is returned. 
Hence, the bucket was not ready.

日本語に訳すと、

「 S3 のバケットには通常 2 つのドメインが割り振られている。片方はバケットが作られてからすぐに利用可能になるが、もう片方のドメインは利用可能になるまでしばらく時間がかかる。そして Cloudfront が S3 からオブジェクトを取得する際に利用するドメインは後者である。Cloudfront は、S3 のドメインが利用可能になるまでの間、307 リダイレクトを返す。」

とのことです。つまり、作ったばかりの S3 バケットを Cloudfront の Origin に指定してしまうと、しばらくの間 Cloudfront から 307 が返るというのが仕様のようです。

へー、知らなかった。

ちなみに、一度 307 が返ったのを確認してしまった場合、 その応答が Cloudfront にキャッシュされている可能性もあるため(未確認)、一応 Invalidation (キャッシュの削除) をしておいた方が安心です。