カテゴリー
[AWS x SEO対応] S3 & CloudFrontで静的ホスティングしたウェブサイトのドメイン移管 ~ 301リダイレクトを仕込む
※ 当ページには【広告/PR】を含む場合があります。
2021/03/14

一例を挙げると、
hoge-s3-blog.jp
piyo-s3-blog.com
301リダイレクト
この時に、AWS S3とCloudFrontを用いたCDN方式のウェブサイトは、通常のレンタルサーバーとは仕組みが違うので、定石である
.htaccess
ということで今回はAWS S3ウェブサイトのお引越しの際特有の301リダイレクト方法に関して考察してみます。
301リダイレクト?
リダイレクトとは読んで字のごとく、特定のURLを踏んだら、別のURLアドレスへ遷移先を変えてくれる機能で、通常
特にドメインのリニューアルに伴うリダイレクトで重要なのは、以下の301と302です。
301 Moved Permanently:
リクエストされたリソースのURLが永遠に変更されたことを示します。
レスポンスで新しいURLが与えられます。
302 Found:
リクエスト元のURLが一時的に変更されたことを示します。
リクエスト元のURLは今後さらに変更される可能性もあるので、
クライアントは引き続き同じURLを使用するべき、と解釈されます。
どちらも結果的にリダイレクトしてくれることには変わりないのですが、「全面的にサイトを移管する」301を使ったほうがよりGoogleなどのクローラーに適切に処置してもらえる可能性があります(今は302を使っても大差はないと言われていますが...)。
では以降では、静的ホスティングしたAWS S3サイトをLambda@Edgeを使って柔軟にドメイン移管させるやり方をやってみます。
なお、サイトを新しいドメインに完全移管する場合には、
リダイレクトの設定を完了した後でGoogleクローラーにインデックスを催促
先にページ構造変更前のsitemap.xmlをSearch Consoleにリクエストしてから、ドメイン間のリダイレクト設定しても意味が無いことに留意してください。
Lambda@Edgeでリダイレクトを自動化
では本記事では、AWS S3上で静的ホスティングで運用しているウェブサイト
piyo-s3-blog.com
hoge-s3-blog.jp
とりあえず前提として先にpiyo-s3-blog.comで配信しているS3バケット内のコンテンツを丸ごと、hoge-s3-blog.jpで配信するS3バケット内へコピーしておいた状態にしておき、リダイレクト先が存在するようにしておきます。
この時にGoogleアナリティクスやタグマネージャーなどの特定サイト監視用のjavascriptスニペットはhtmlリソースから外したり、Googleアドセンスのような参加中のアフィリエイトプログラムで、ドメインごとに審査があるようなもののリンクは消去しておくと、まさかの時のペナルティーを避けることが出来るので、移管するサイトによっては色々とサイトコピー時のケアを考える必要があります。
AWS S3から柔軟なHTTPレスポンス操作をするのには
Lambda@Edgeは元々、CloudFrontの得意な今回のような静的なコンテンツ配信を行う機能に、Lambdaが力添えをしてURLのプレフィックス処理など動的な制御を行えるようにしたサービスです。
他にもLambda@Edgeは色々と魅力的なユースケースがあるようですが、今回はさらなる応用例として301リダイレクトの手順を以降で説明していきます。
Lambda関数の作成
基本的に前回説明した
前回からの修正点としては
index.js
今回の例として、引っ越し元のドメインである
piyo-s3-blog.com
hoge-s3-blog.jp
模式図的に表すと以下のようになります。

なお、
piyo-s3-blog.com/piyo
piyo-s3-blog.com/fuga
hoge-s3-blog.jp/fuga
するとLambda@Edgeのコードは以下のようになります。
const convertMap = {
'/fuga/index.html': 'https://hoge-s3-blog.jp/fuga/index.html',
//👇リダイレクトしたいURLを連想配列として追加...
'/mofu/index.html': 'https://hoge-s3-blog.jp/mofu/index.html',
//...
};
exports.handler = async (event, context, callback) => {
const request = event.Records[0].cf.request;
const uri = request.uri;
const uriMod = uri.replace(/\/$/, '\/index.html').replace(/\/([^\.\/]+)$/, '/$1/index.html');
const val = convertMap[uriMod];
if(val !== undefined) {
console.log('+++ Redirect To +++');
console.log(val);
const redirectRes = {
status: '301',
statusDescription: 'Moved Permanently',
headers: {
location: [{
key: 'Location',
value: val,
}],
},
};
return callback(null, redirectRes);
} else {
console.log('+++ Direct To +++');
console.log(uriMod);
request.uri = uriMod;
return callback(null, request);
}
};
ちなみにこのLambda@Edgeをデプロイするときにトリガーするターゲットは
piyo-s3-blog.com
Lambda関数の動作確認
軽い動作確認用に適当な名前を付けてテストを作ってみます。
まずはリダイレクトしないケースのリクエスト用テストスニペットを以下の用に作成します。
{
"Records": [
{
"cf": {
"config": {
"distributionId": "EXAMPLE"
},
"request": {
"headers": {
"host": [
{
"key": "Host",
"value": "d123.cf.net"
}
],
"user-name": [
{
"key": "User-Name",
"value": "CloudFront"
}
]
},
"clientIp": "1111:2222:3333:4444",
"uri": "/piyo",
"method": "GET"
},
"response": {
"status": "200",
"statusDescription": "OK",
"headers": {
"x-cache": [
{
"key": "X-Cache",
"value": "Hello from Cloudfront"
}
]
}
}
}
}
]
}
これをテストすると、以下のように通常のアクセスと変わらないレスポンスが得られるはずです。
Response
{
"headers": {
"host": [
{
"key": "Host",
"value": "d123.cf.net"
}
],
"user-name": [
{
"key": "User-Name",
"value": "CloudFront"
}
]
},
"clientIp": "1111:2222:3333:4444",
"uri": "/piyo/index.html",
"method": "GET"
}
Function Logs
START RequestId: ************************** Version: $LATEST
2021-03-14T08:24:23.279Z ****************** INFO +++ Direct To +++
2021-03-14T08:24:23.282Z ****************** INFO /piyo/index.html
END RequestId: **************************
REPORT RequestId: ************************* Duration: 5.96 ms Billed Duration: 6 ms Memory Size: 128 MB Max Memory Used: 65 MB Init Duration: 148.17 ms
では次にリダイレクトするテストケースを作成します。 先程のレスポンスの内容で
uri
/fuga
{
"Records": [
{
"cf": {
//...
"uri": "/fuga",
//...
これでコードのテストを実行すると、以下のようなリダイレクトした結果のレスポンスを得ると成功です。
Response
{
"status": "301",
"statusDescription": "Moved Permanently",
"headers": {
"location": [
{
"key": "Location",
"value": "https://hoge-s3-blog.jp/fuga/index.html"
}
]
}
}
Function Logs
START RequestId: ********************* Version: $LATEST
2021-03-14T08:17:18.965Z ************* INFO +++ Redirect To +++
2021-03-14T08:17:18.965Z ************* INFO https://hoge-s3-blog.jp/fuga/index.html
END RequestId: *********************
REPORT RequestId: ******************** Duration: 2.44 ms Billed Duration: 3 ms Memory Size: 128 MB Max Memory Used: 65 MB
動作を確認したら本番用のLambdaをデプロイすると上手くリダイレクトすると思います。
まとめ
今回はAWS S3 & CloudFrontでコンテンツ配信しているパターンのウェブサイトで、どうリダイレクトを実現するのかをLambda@Edgeで行ってみました。
このテクニックを使うと、ウェブサイトのドメインを全面的に移行する際に、これまでのサイト内のリンクを貼ってもらっていたサイトユーザーにも自動で移動後のページに誘導できるようになります。
とはいえ、引っ越し元のドメインが有効期限が切れるまでには、サイトを移管した旨が伝わるようにしっかり事後処理する必要があることには変わりませんので、サイトの全面的なリニューアルには十分余裕をもったスケジュールで臨みたいものです。
参考サイト
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー