WebアプリケーションのCD(継続的デリバリー)で、パスベースのURLを採用したSPAの場合、
${SHA_HASH}.domain.name -> origin/index.${SHA_HASH}.html
のようなrewriteをしたいことが良くあります。
/${SHA_HASH}/**/* -> /${SHA_HASH}/index.html
にrewriteする方法もありますが、本番とパスの階層が変わってしまって、ステージングテストで苦労することになるので、ドメインベースにしたいわけです。
これは、nginxやApacheでもできますが、このためだけにnginxやApacheを立ち上げるのもばからしいので、Lambda@Edgeでできないかと思うわけです。結論から言うと問題なくできます。
- Cloud Frontでのワイルドカードドメインの利用
- デプロイ前に、index.html -> index.${SHA_HASH}.htmlにリネーム。
など、面倒なことがいろいろありますが、ソースコードだけで言うと以下のようにすればとりあえず動きます。
exports.handler = async (event, context) => {
const request = event.Records[0].cf.request;
if(!request.uri.match(/^\/(?:js\/|css\/|img\/|favicon.ico)/)) {
const host = request.headers.host[0].value;
const hostMatch = host.match(/^([0-9a-f]{40}|[a-z]{3,}-?[0-9]*)\./);
const versionId = hostMatch ? hostMatch[1] : "production";
request.uri = `/index.${versionId}.html`;
console.log(request.uri);
}
return request;
};
あまり汎用性のないコードですが、ドメイン名やuriの取得・変更する部分は共通だと思うので、参考になると幸いです。
ちなみに、本来、request.uri.matchの部分は、Cloud Front側でやってしまった方がパフォーマンス面でもコスト面でも良いでしょう。