AWS と Terraform のお勉強として GitHub Pages モドキをつくりました。
作ったもの
AWS 上に GitHub Pages のような静的サイトホスティングシステムを構築する Terraform モジュールを書きました。
https://github.com/kmn4/terraform-modules
このモジュールで作成されるシステムは、git push にトリガーされてサイトをビルドし、CDN へデプロイします。
CodeBuild を使用しているため、ビルド定義には buildspec.yml が使えます。
もちろんサイトは HTTPS で配信されます。証明書発行まで Terraform が自動で行います。
サイトのビルドをメールで通知したり、ウェブサイトに Basic 認証を設定したりもできます。
GitHub Pages と比べたときの独自性としては
- リポジトリがデフォルトでプライベート
- サイトビルド後に既存の CDN キャッシュを無効化するので次回訪問者が確実に更新されたコンテンツへアクセスする……はず
- ID/パスワードを知っている人のみが閲覧できるサイトを作れる
全体の構成図
こんな感じ。
- CodePipeline は仰々しい感じがしたので Lambda で代用します。
- サイトコンテンツ用のバケットとアクセスログ用のバケットがあります。
- ビルド通知メールの件名をカスタマイズしたかったので CodeStar Notifications の代わりに EventBridge と Lambda を使っています。
システムの振る舞い
サイト訪問時
- 名前解決: Cloudflare が CloudFront のドメイン名を応答 → AWS の名前サーバが IP アドレスを応答
- 訪問者が CloudFront に HTTP リクエスト
- CloudFront が S3 オリジンからページを取得
- 別の S3 バケットにアクセスログを記録
認証を行う場合は、1. で CloudFront Function により Basic 認証します
git push したとき
- CodeCommit リポジトリへ
git push - CodeCommit トリガーがリポジトリの変更を Lambda に通知
- Lambda が CodeBuild を開始
- CodeBuild がリポジトリをクローンしてウェブサイトをビルド
- CodeBuild の状態変更が EventBridge を通じて Lambda へ通知
- Lambda が SNS (Simple Notification Service) トピックへメッセージを publish
- SNS が開発者へメッセージを配信
- ビルド生成物を S3 バケットへミラーリング 1
- サイトの更新を確実にするため CloudFront キャッシュを削除 1
今後の課題
- クライアント認証に Cognito を使ってみる。
- Hugo 以外の方法でもサイトを作ってみる。React で作ったツール集とか面白そう。
- ビルド通知を Slack 化する。
- ビルドで更新されたパスだけキャッシュを invalidate する
実は
Cloudflare Pages を使えば上記の「独自性」をすべて簡単に実現できるという説がある。
僕が作るものは既にあるものじゃーーん