ブログを GCP から AWS に移行した。
概要
Before
- Google Cloud Platform
- f1-micro インスタンスで CoreOS が動作していた。
- sinatra の Docker コンテナが動的なコンテンツを返していた。
- とはいえほぼ静的な html なので、 SSL 終端もしていた nginx コンテナに強めのキャッシュを持たせていた。
After
- Amazon Web Services
- 予めビルドした静的コンテンツを S3 に放り込む。
- S3 + CloudFront(CDN) + ACM(SSL) + Lambda@Edge で配信。
詳細
GCP は Always Free という無料枠で f1-micro インスタンスを使わせてくれるのだが、これはもう滅茶苦茶弱いマシンなんですよね。使うにしても色々工夫して使わないといけなかった。
しかも無料かと思いきや Static IP Charge という概念があり、 IP アドレスを確保していると課金が月々 700 ~ 800 円くらい発生はしていて、これはサーバーとして使うならほぼ必須な訳だし、無料とは…という気持ちでなんとなくモヤモヤはしつつも惰性でお金を払っていた。
使っていた CoreOS も 2020/5/26 で EOL となり別途 Fedora CoreOS などの後継に移行する必要もあったが、それをやるくらいならもうエイヤで大工事してしまおう、とはずっと思っていたのだけど、 めんどくさくて 中々手を付けられずにいて、いやしかし、もうそうも言ってられん、ということで土日に一念発起して大工事をして移行に大成功したという経緯です。
sinatra アプリケーションで動的に生成しているコンテンツをどうやって配信できる静的な形にするか
S3 + CloudFront で配信するということは事前に静的ファイルに全てをレンダリングしておく必要がある訳だが、これをどう実現するかについて良いアイデアが思い付かずしばらく困っていた。
しかし手元に sinatra アプリケーションサーバーを立ち上げて localhost
のドメイン制限を掛けつつ wget
で辿れるだけ辿ってダウンロードすることを思い付き、それが割と良かったのでそうしている。
元来はクローラーのための機能だとは思うのだけどこういう使い方もできますね。
あとは生成されたファイルを雑に aws s3 sync ...
してやって aws cloudfront create-invalidation ...
してやれば良い。
厳密には今までの実装とは HTTP ヘッダなどの返ってくる値が変わったりしてるし、手持ちの他のドメインからのアクセスがあった場合は丁寧にリダイレクトするなどの処理も挟んでいたりしたのが無くなってしまったりと、破壊的な変更が発生もしているが、実際のところ何も致命的な問題はないので良しとしている。
Lambda@Edge について
これはもうしょうがないんだけど S3 + CloudFront で静的サイトを配信する場合サブディレクトリの index.html を拾ってくれない。
S3 を Web サイトとしてホスティングする機能を使ってやれば一応解決はするが、 S3 を直で見る URL で参照できてしまうのはあまり格好良くないので今回は Lambda@Edge を挟んで解決した。個人のブログ程のアクセスに対する使用なら料金は恐らく誤差レベルになると思われる。
cloudfront subdir index
などでググれば実装例は沢山見付かるので、中身を良く読みつつ良い感じになんやかんやすれば良い。
締め
今までは f1-micro インスタンスが弱すぎて CoreOS がセルフアップデートのタイミングで自身の負荷に耐えられずインスタンスが落ちてたり、上手く行っても再起動のタイミングでダウンタイムが発生したりしていたが、この構成では原理的にダウンタイムが発生しなくなったので重い腰を上げてやってよかったとは思っている。
というか S3 + CloudFront の基盤で配信してるサイトが落ちるようなことがあった場合、恐らくそれは第三次世界大戦で地球が焦土と化しており人々はインターネットしてるどころではないレベルの末世であると思われるので、特にその辺りを気にする必要はない。
しかもこの構成だと安くなったんじゃないかな。来月の請求を見ないと何とも言えないけど。