S3のRedirection Rulesを利用してリダイレクトする2

2014.03.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

前回はS3のRedirection Rulesを利用したリダイレクト方法について紹介しましたが、以下の様なツイートを見かけましたので検証してみました。結論としてはHttpErrorCodeReturnedEqualsを利用するだけで実現できそうでした。

やりたいことはS3にアクセスしてファイルが存在しない(404)の場合に生成サーバにリダイレクト出来ればよいということになるはずです。ということで以下の構成だったとして404の場合に生成サーバにリダイレクトできることを確認していきたいと思います。なお、今回もRoute 53でドメインを振らずにS3のStatic Website Hostingのドメインで進めていきます。

サムネールサーバ http://thumbnail.example.com.s3-website-ap-northeast-1.amazonaws.com/
生成サーバー http://origin.example.com/

HttpErrorCodeReturnedEqualsによるリダイレクト

まずはS3バケットを用意します。ここではthumbnail.example.comというバケットを用意した前提で進めます。まずはcurlコマンドからアクセスできるようにBucket Policyを設定します。[Permissions]をクリックして[Edit bucket policy]ボタンをクリックして下さい。[Bucket Policy Editor]画面が表示されるので以下のポリシーを入力します。このポリシーによって誰でもバケットの全オブジェクトを参照できるようになります。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "AddPerm",
			"Effect": "Allow",
			"Principal": {
				"AWS": "*"
			},
			"Action": [
				"s3:GetObject"
			],
			"Resource": [
				"arn:aws:s3:::thumbnail.example.com/*"
			]
		}
	]
}

では、実際にcurlコマンドでアクセスできるようになっているか確認します。ここではhttp://thumbnail.example.com.s3-website-ap-northeast-1.amazonaws.com/hoge/fuga.pngにアクセスしてみます。なお、まだファイルをアップロードしていないので当然404エラーになるはずです。

[~]$ curl -I http://thumbnail.example.com.s3-website-ap-northeast-1.amazonaws.com/hoge/fuga.png
HTTP/1.1 404 Not Found
x-amz-error-code: NoSuchKey
x-amz-error-message: The specified key does not exist.
x-amz-error-detail-Key: hoge/fuga.png
x-amz-request-id: E26AF6B9D86148CB
x-amz-id-2: QK7cP0f8oQue7mJ6qF/b34/ejhZWkRxcOaVvaxhZgvnbCM/gHFFDNR58hxaq8cqC
Transfer-Encoding: chunked
Date: Thu, 06 Mar 2014 15:14:03 GMT
Server: AmazonS3

404 Not Foundが返ってきていますね。

次にバケットの[Properties]をクリックして[Static Website Hosting]を開き[Enable website hosting]を選択します。そして[Edit Redirection Rules:]に以下の内容を入力します。HttpErrorCodeReturnedEqualsタグに404と入力していますが、この設定によって404の場合にのみRedirectタグに書かれた内容が実行されます。つまり404の場合はorigin.example.comにリダイレクトするという意味になります。なお[Index Document:]は必須項目であるためindex.htmlと入力しています。

<RoutingRules>
    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <HostName>origin.example.com</HostName>
        </Redirect>
    </RoutingRule>
</RoutingRules>

では、実際にcurlコマンドでリダイレクトされるか確認します。

[~]$ curl -I http://thumbnail.example.com.s3-website-ap-northeast-1.amazonaws.com/hoge/fuga.png
HTTP/1.1 301 Moved Permanently
x-amz-id-2: uMIgvCOgsy6gYxliqgwR0ybLXobPFTltKE7fuwK54fag7fXQtjEOHMafWfPlm14E
x-amz-request-id: D1C3A3A2DB57B453
Date: Thu, 06 Mar 2014 15:18:00 GMT
Location: http://origin.example.com/hoge/fuga.png
Content-Length: 0
Server: AmazonS3

Locationヘッダがhttp://origin.example.com/hoge/fuga.pngになっていますね!

最後にhogeフォルダを作り、fuga.pngをアップロードするとリダイレクトされないことを確認して下さい。実際に/hoge/fuga.pngを用意してからcurlコマンドでアクセスした結果は以下になります。

[~]$ curl -I http://thumbnail.example.com.s3-website-ap-northeast-1.amazonaws.com/hoge/fuga.png
HTTP/1.1 200 OK
x-amz-id-2: 8Ymb52xkqpPgLveTcoqFWCS8KeUX5bwFqoHRUUdBbqJ3VH/g8Z3+A3LLQXgVTWOv
x-amz-request-id: 28BF0E3BC8920E0B
Date: Thu, 06 Mar 2014 15:21:34 GMT
Last-Modified: Thu, 06 Mar 2014 15:21:27 GMT
ETag: "d41d8cd98f00b204e9800998ecf8427e"
Content-Type: image/png
Content-Length: 0
Server: AmazonS3

200 OKになっていますね。

ディレクトリのマッピングを変えたい場合

KeyPrefixEqualsタグを併用することで生成サーバにリダイレクトする際のディレクトリのパスを変更することができます。前述の例であればfugaディレクトリへのアクセスをpiyoディレクトリにリダイレクトすることができます。[Edit Redirection Rules:]の内容を以下に変更して下さい。変更点はKeyPrefixEqualsタグとReplaceKeyPrefixWithタグを追加した点です。KeyPrefixEqualsタグにhogeと入力していますが、この設定によってパスがhogeから始まる場合はRedirectタグに書かれた内容が実行されます。今回の場合は404かつパスがhogeから始まる場合はorigin.example.comにリダイレクトするという意味になります。またReplaceKeyPrefixWithタグにはpiyoと入力していますが、この設定によってKeyPrefixEqualsタグにマッチしたパスはReplaceKeyPrefixWithタグの値に置換されます。そのため、origin.example.com/piyoにリダイレクトするという意味になります。

<RoutingRules>
    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
            <KeyPrefixEquals>hoge</KeyPrefixEquals>
        </Condition>
        <Redirect>
            <HostName>origin.example.com</HostName>
            <ReplaceKeyPrefixWith>piyo</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
</RoutingRules>

では、実際にcurlコマンドでリダイレクトされるか確認します。今回はfugafuga.pngにアクセスしてみます。ついでにパラメータとして?key=valueも付けてみました。

[~]$ curl -I http://thumbnail.example.com.s3-website-ap-northeast-1.amazonaws.com/hoge/fugafuga.png?key=value
HTTP/1.1 301 Moved Permanently
x-amz-id-2: 7Myj31Ktbh12lvAAHaIQGSFVBTTz1pmIf0hXfsBPYg7V1ZldGoshGx0HvlzTf12z
x-amz-request-id: 23D0285140C781D7
Date: Thu, 06 Mar 2014 15:47:38 GMT
Location: http://origin.example.com/piyo/fugafuga.png?key=value
Content-Length: 0
Server: AmazonS3

Locationヘッダがhttp://origin.example.com/piyo/fugafuga.png?key=valueになっていますね!そうです、ReplaceKeyPrefixWithタグの場合はパラメータはそのまま引き継がれます。前回のReplaceKeyWithタグの場合はパスだけでなくパラメータも削除されていたので、目的に応じてタグを使わけて下さい。

まとめ

Redirection Rulesは高度なリダイレクトルールを指定することもできると公式ドキュメントに書いてありましたが、かなり柔軟な設定ができることが分かりましたね。もちろんEC2インスタンス上にWebサーバーを構築すれば柔軟な設定ですが、S3で実現できるのであれば手軽ですしコストも下げられますよね。ということで、みなさんの環境でも利用できないか是非試してみてください。