計画メンテナンスでサイトを一時的に閉じる時、ブラウザでアクセスしてくる一般ユーザにはメンテナンスページを返せば十分だけれども、
検索ボットにはメンテナンスページの HTTP ステータスコードを 503:Service Unavailable
で返すのが好ましい。
Official Google Webmaster Central Blog: How to deal with planned site downtime
メンテナンスページは静的という前提のもと、AWS の DNS サービス route53 と CDN サービス CloudFront とストレージサービス S3 を組み合わせで実現してみる。
route53-ELB-EC2 というようなサーバ構成の場合、メンテナンスの前後で route53 の Alias Target
を本番用の ELB からメンテナンスページ用の CloudFront にかえるだけで済む。
S3 の設定
メンテナンスページ用のバケットを作成。(名前は bucket-4-maintenance
とする)
メンテナンスページを 503.html
というキーでアップロードする。
S3 バケットは検証しやすいように Static Website Hosting
する。
存在する/しないキーにアクセスした時のステータスを確認
存在するキー(503.html
) にアクセスすると、 200 OK
がかえってくる
] $ curl -D - http://bucket-4-maintenance.s3-website-ap-northeast-1.amazonaws.com/503.html HTTP/1.1 200 OK x-amz-id-2: Le4RMNGtAOaPTIT+W1U4ZOeGdROlwKvpP4JNQC92PN3ry2KNIE3TA9tCzeG7m1163d4YVeLQHog= x-amz-request-id: ED7863C9455D2903 Date: Sat, 24 Jan 2015 15:52:47 GMT Last-Modified: Sat, 10 Jan 2015 13:44:56 GMT ETag: "a3076cabbe20cb3498db339dd5fca8d4" Content-Type: text/html Content-Length: 37 Server: AmazonS3 <html> <body> 503 </body> </html>
存在しないキー(404) にアクセスすると、 403 Forbidden
がかえってくる
] $ curl -D - http://bucket-4-maintenance.s3-website-ap-northeast-1.amazonaws.com/404 HTTP/1.1 403 Forbidden x-amz-request-id: 41B0885DD66A2F2D x-amz-id-2: iyDQcN6770EeLkQnWV8QHiwbcrJ+Ujbd3djpxKsbKClrHZpdGUyjFRXF3PrFpjFJpi+YFsmCAFk= Content-Type: text/html; charset=utf-8 Content-Length: 303 Date: Sat, 24 Jan 2015 15:55:55 GMT Server: AmazonS3 <html> <head><title>403 Forbidden</title></head> <body> <h1>403 Forbidden</h1> <ul> <li>Code: AccessDenied</li> <li>Message: Access Denied</li> <li>RequestId: 41B0885DD66A2F2D</li> <li>HostId: iyDQcN6770EeLkQnWV8QHiwbcrJ+Ujbd3djpxKsbKClrHZpdGUyjFRXF3PrFpjFJpi+YFsmCAFk=</li> </ul> <hr/> </body> </html>
S3 レイヤーで各オブジェクトの HTTP ステータスコードをカスタマイズできると楽なのだけれど、 S3 だけではカスタマイズできないので、CloudFront の力を借りる。
CloudFront の設定
メンテナンスするドメインをほぼ空っぽの S3 バケットに向けると、リクエストに対応する S3 オブジェクトが存在しないので 403 エラーが発生する。
S3 の前段に CloudFront を挟み、S3 の 403 エラーのレスポンスコードとレスポンスボディーをメンテナンス向けのものにカスタマイズさせる。
ディストリビューションの追加
メンテナンスページ用の web distribution を新規追加する。
Origin Settings
のOrigin Domain Name
には先ほど作成した S3 バケットを指定する。Distribution Settings
のAlternate Domain Names(CNAMEs)
にメンテナンス対象のサイトのドメインを指定する。
エラーページのカスタマイズ
追加したディストリビューションの Error Pages
タブの「Create Custom Error Response」ボタンからエラーレスポンスをカスタマイズ(Customize Error Response=Yes
)する。
HTTP Error Code
には S3 でオブジェクトが見つからなかった時に返ってくる 403:Forbidden を指定。Resonse Page Path
には先ほど追加したバケットにあるメンテナンスページのパスを指定。HTTP Response Code
には 503:Service Unavailable を指定。
この機能はあくまでも Custom Error Response なので、 2xx, 3xx 系の正常系レスポンスはカスタマイズできない。
CloudFront にアクセス
S3 に存在するキーで CloudFront にアクセスする。
] $ curl -D - http://subdomain-4-maintenance-s3.cloudfront.net/503.html HTTP/1.1 200 OK Content-Type: text/html Content-Length: 37 Connection: keep-alive Date: Sat, 24 Jan 2015 16:10:47 GMT Last-Modified: Sat, 10 Jan 2015 13:44:56 GMT ETag: "a3076cabbe20cb3498db339dd5fca8d4" Server: AmazonS3 Age: 933 X-Cache: Hit from cloudfront Via: 1.1 7462cb1e6b64f411620ece43e93d9999.cloudfront.net (CloudFront) X-Amz-Cf-Id: YRmDRbUnWube9vyEODb-plyqvgKG9oSTCDke8YdAnhUZQkb9Zi4iSA== <html> <body> 503 </body> </html>
ステータス 200:OK
S3 に存在しないキーでCloudFront にアクセスする。
] $ curl -D - http://subdomain-4-maintenance-s3.cloudfront.net/404 HTTP/1.1 503 Service Temporarily Unavailable Content-Type: text/html Content-Length: 37 Connection: keep-alive Date: Sat, 24 Jan 2015 16:10:47 GMT Last-Modified: Sat, 10 Jan 2015 13:44:56 GMT ETag: "a3076cabbe20cb3498db339dd5fca8d4" Server: AmazonS3 Age: 918 X-Cache: Hit from cloudfront Via: 1.1 3f60678c2a9a9452e31c453bab6c8888.cloudfront.net (CloudFront) X-Amz-Cf-Id: rM0M6FSqjp5gZc1DDDXexOFxEzAiRgwW_GMhybeKsL_kH-d_pTNxhg== <html> <body> 503 </body> </html>
HTTP ステータス 503 Service Temporarily Unavailable で Custom Error Response
の Response Page Path
で指定した 503.html のボディーがかえってきている。
Route 53 の設定
作成した CloudFront をメンテナンス先ドメインに紐付ける。
Alias を Yes にすると、 Alias Target
に設定可能な ELB, S3, CloudFront などの一覧が表示される。
先ほど追加した CloudFront の Domain Name を指定する。
Route53 にアクセス
S3 に存在するキーでアクセスする。
] $ curl -D - http://cdn.example.com/503.html HTTP/1.1 200 OK Content-Type: text/html Content-Length: 37 Connection: keep-alive Date: Sat, 24 Jan 2015 16:10:47 GMT Last-Modified: Sat, 10 Jan 2015 13:44:56 GMT ETag: "a3076cabbe20cb3498db339dd5fca8d4" Server: AmazonS3 Age: 20 X-Cache: Hit from cloudfront Via: 1.1 f09dadf7d4655585583b2883d9900000.cloudfront.net (CloudFront) X-Amz-Cf-Id: WtAPpRDippH58m6XPjAkpr63blrQczWG_MSk5Ep1yzU9bg0CkwRPAw== <html> <body> 503 </body>
S3 に存在しないキーでアクセスする。
] $ curl -D - http://cdn.example.com/404 HTTP/1.1 503 Service Temporarily Unavailable Content-Type: text/html Content-Length: 37 Connection: keep-alive Date: Sat, 24 Jan 2015 16:10:47 GMT Last-Modified: Sat, 10 Jan 2015 13:44:56 GMT ETag: "a3076cabbe20cb3498db339dd5fca8d4" Server: AmazonS3 X-Cache: Miss from cloudfront Via: 1.1 ae575387dd32f9e6aae0bb6e63f51111.cloudfront.net (CloudFront) X-Amz-Cf-Id: c7FxjqWyW-soYNqN_zPZaIq-h9YQcBTIhgx2sRrIQo8-tSRhHmAzVA== <html> <body> 503 </body> </html>
HTTP ステータス 503 Service Temporarily Unavailable で Custom Error Response の Response Page Path で指定した 503.html のボディーがかえってきている。
References
- Customizing Error Responses – Amazon CloudFront
http://docs.aws.amazon.com/console/cloudfront/custom-error-responses - Official Google Webmaster Central Blog: How to deal with planned site downtime
http://googlewebmastercentral.blogspot.com/2011/01/how-to-deal-with-planned-site-downtime.html - How CloudFront Processes and Caches HTTP 4xx and 5xx Status Codes – Amazon CloudFront
http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/HTTPStatusCodes.html - Hosting a Static Website on Amazon S3 – Amazon Simple Storage Service
http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html