個人ブログ「あれこれびより」を公開しました!
このブログでは、技術メモ、ガジェットレビュー、日常の工夫など、名前のとおり「あれこれ」を少しずつ書いていく予定っす! せっかくならブログ自体も自分で作ってみよう、ということでAstroとAWSを使って静的サイトとして組んでみました!
この記事では、どんな構成で作ったのか、公開までにどんなところを触ったのかをざっく~り紹介します。 細かい手順は、今後の記事で少しずつ掘り下げていく予定っすね!
なぜ自分でブログを作ったのか
ブログを書くなら、WordPressや既存のブログサービスを使う方法もあります。 自分もnoteを使用してマイクラ記事を書いたことがありますね。 記事を書くことだけを考えるなら、たぶんそのほうが早いと思います。
ただ今回は、Webサイト構築、AWS、GitHub Actions、Infrastructure as Code、SEOまわりも実際に触ってみたかったんですよね。 読むだけだと分かった気になって終わりがちなので、学習も兼ねて自作してみることにしました。 んで、できれば今後も長く公開していきたいですね( ^)o(^ )
技術構成
このブログでは、主に次の技術を使っています。
- Astro
- TypeScript
- Markdown / MDX
- GitHub
- GitHub Actions
- Amazon S3
- Amazon CloudFront
- Amazon Route 53
- AWS Certificate Manager
- AWS CloudFormation
- GitHub Actions OIDC
- Amazon CloudWatch
- Amazon SNS
- AWS Budgets
EC2、Lambda、RDS、DynamoDBのようなサーバーやデータベースは使っていません。 記事を静的ファイルとして生成し、S3とCloudFrontで配信する構成にしています。
全体の流れは、かなり単純化するとこんな感じです。
- GitHubで記事やソースコードを管理する
- GitHub ActionsでAstroをビルドする
- 生成された
dist/をAmazon S3へ置く - Amazon CloudFrontから配信する
- Route 53で
https://arekore-biyori.comへ向ける
細かく見ると証明書やIAMも出てきますが、まずは「GitHubで管理して、S3に置いて、CloudFrontで配る」と考えると分かりやすいっすね。
Astroで静的サイトにする
記事はMarkdownまたはMDXで管理しています。 通常の記事はMarkdown、記事内でコンポーネントを使いたい場合はMDX、という使い分けっすね。
npm run build を実行すると、Astroが dist/ にHTML、CSS、画像参照などの静的ファイルを生成してくれます。
ブログはコメント機能やログイン機能が必須ではないので、静的サイトとの相性はかなりよさそうです。
コメント機能は今後実装していきたいかも…w
表示も軽くしやすいですし、サーバー管理をあまり意識しなくてよいのも助かるところです。
S3は直接公開しない
S3にはビルド後のファイルを置きますが、S3バケット自体は一般公開していません。 Public Access Blockを有効にして、CloudFrontからだけ読めるようにしています。
この接続にはCloudFront Origin Access Control、略してOACを使っています。 S3を直接公開するよりも、配信の入口をCloudFrontに寄せられるので、管理しやすいというわけです。
独自ドメインとHTTPS
本番URLは https://arekore-biyori.com です。
ドメインとDNSはRoute 53で管理し、HTTPS用の証明書はAWS Certificate Managerで発行しました。 CloudFrontに証明書を設定して、Route 53のAレコードとAAAAレコードのAliasでCloudFrontへ向けています。
DNS、証明書、CloudFrontの組み合わせは、最初ちょっとややこしかったっすね~。マジでわからんかった… ただ、一度流れが見えると「ドメインをCloudFrontへ向ける」「CloudFrontで証明書を使う」という役割分担が少しずつ見えてきました。
GitHub Actionsでデプロイする
デプロイはGitHub Actionsから手動実行できるようにしています。 流れはこんな感じです。
- リポジトリをcheckoutする
- Node.jsをセットアップする
npm ciで依存関係を入れるnpm run check:contentで記事の設定を確認するnpm run check:imagesで画像参照を確認するnpm run buildで静的ファイルを生成する- OIDCでAWSのIAM Roleを引き受ける
dist/をS3へ同期する- CloudFrontのキャッシュを無効化する
本番デプロイにはGitHubのproduction Environmentを使っています。
GitHub Actions OIDCを使う
AWSへデプロイするために、長期のAWSアクセスキーはGitHubに保存していません。 代わりにGitHub Actions OIDCを使って、実行時だけAWSのIAM Roleを引き受ける形にしています。
workflow側では id-token: write を許可し、AWS側ではGitHubのrepository、branch、environmentなどを条件にして、信頼できる実行元を絞っています。
repository IDやowner IDのような、名前変更に強い識別子も条件に入れる方針にしました。
IAMまわりは特に難しかった~… CloudFormation実行時に権限不足で失敗することもあり、どのロールが何を作れる必要があるのかを一つずつ確認しながら進めました。
CloudFormationで管理する
AWSリソースはCloudFormationで管理しています。 メインのスタックでは、主に次のリソースを作っています。
- S3バケット
- CloudFront Distribution
- CloudFront OAC
- CloudFront Function
- Response Headers Policy
- GitHub OIDC Provider
- GitHub Actions用のDeploy Role
監視用のスタックでは、次のリソースを分けて管理しています。
- CloudWatch Alarm
- SNS Topic
- AWS Budgets
手作業で作るよりも、あとから見直しやすくなるのがよいところです。 一方で、IAMやCloudFrontの細かい設定は書き間違えると分かりにくいので、少しずつ確認しながら進めるのが大事っすね。
CloudWatchとSNSで通知する
公開後の簡単な監視として、CloudFrontのエラー率をCloudWatch Alarmで見ています。 対象にしているのは、TotalErrorRateと5xxErrorRateです。 しきい値を超えたら、SNS経由でメール通知が届くようにしています。
公開直後には、S3へまだコンテンツをデプロイする前のAccessDeniedなどがCloudFrontの4xxとして記録され、TotalErrorRateのアラームが発生しました。 一瞬びっくりしましたが、通知がちゃんと動いている確認にもなりました。
AWS Budgetsで費用を見る
個人ブログなので、コストも見えるようにしておきたいところです。 今回は月額10 USDを目安の予算として設定し、実利用額や予測額が一定ラインを超えたら通知されるようにしました。
CloudFrontやS3は、小規模な静的ブログなら比較的低コストで始めやすい構成だと思います。 それでも、設定ミスや想定外のアクセスに気づけるようにしておくと安心っすね。
作ってみた感想
実際に作ってみると、サイトそのものより周辺インフラのほうが大変でしたね。
Astroでページを作る部分ももちろん楽しいんですが、DNS、HTTPS、CloudFront、S3のアクセス制御、IAM、OIDC、GitHub Actions、CloudFormation、監視、コスト管理と、触るものがけっこう多かったです。
特にIAMは、分かったつもりでも実際に動かすとつまずきやすいところでした。 ただ、失敗しながら直していくことで、どの権限がどこで必要なのかを少しずつ理解できた気がします。
今後書いていきたいこと
この記事は、ブログ構築の総論として書いています。 今後は、もう少し細かい単位で記事にしていきたいです。
- Astroでブログを作る流れ
- S3とCloudFrontで静的サイトを公開する方法
- Route 53で独自ドメインを使う方法
- ACMでHTTPSを設定する流れ
- GitHub Actions OIDCでAWSへデプロイする方法
- CloudFormationでブログ基盤を作る考え方
- CloudWatchとSNSで簡単に監視する方法
まだ個別記事がないものも多いので、書けたものから少しずつ増やしていきます。
まとめ
「あれこれびより」は、Astro、GitHub、AWSを使って構築しました。 記事はMarkdownやMDXで管理して、GitHub ActionsからS3へデプロイし、CloudFront経由で配信しています。
また、OIDCで長期アクセスキーを使わないデプロイにして、CloudWatch、SNS、AWS Budgetsで最低限の監視とコスト確認も入れています。
まだ改善したいところはありますが、ブログ自体も育てながら、学んだことを記事として残していければと思います。
あと、自分の旅日記や何かのレビューとかしていきたいですね。w