はじめに
今後は自分のブログにアウトプットして育てていきたいと思います。
https://wan0ri.com/
概要
- AWS と Hugo の組み合わせで技術ブログを構築した。
-
staging
: リポジトリ公開用。stagingはローカル検証用で構築したので ACM と Route53 の構築は省略。
-
prod
: リポジトリはPrivateで管理。
https://github.com/kazukifukuyama14/techblog-staging
コンセプト条件の整理
条件 |
技術選定の方向性 |
コストを抑える |
無料枠や低料金サービスを活用 |
フロント/バックエンド知識が浅い |
GUIや簡単なCLIで操作可能なツールを選定 |
インフラはTerraformで管理 |
IaC(Infrastructure as Code)を前提に構成 |
ドメインと証明書はRoute 53とACMで管理 |
AWSサービスで統一管理 |
推奨技術スタック一覧
機能 |
推奨技術 |
理由 |
静的サイト生成 |
Hugo |
高速・簡単・Markdownベース |
ストレージ & ホスティング |
Amazon S3 |
静的サイトホスティングに最適、無料枠あり |
CDN配信 |
Amazon CloudFront |
高速配信、ACMと連携可能 |
ドメイン管理 |
Amazon Route 53 |
DNS管理、Terraform対応 |
SSL証明書 |
AWS Certificate Manager (ACM) |
無料、CloudFrontと連携可能 |
IaC管理 |
Terraform |
AWS全体をコードで管理可能 |
CI/CD |
GitHub Actions |
Hugoビルド → S3アップロードを自動化可能 |
プロジェクトディレクトリ構成(詳細版)
本番環境では以下構成で構築しました:
aws-hugo-blog/
├── hugo-site/
│ ├── config.toml
│ ├── content/
│ ├── layouts/
│ ├── static/
│ └── themes/
│
├── terraform/
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ ├── terraform.tfvars
│ ├── provider.tf
│ ├── modules/
│ │ ├── s3/
│ │ ├── cloudfront/
│ │ ├── route53/
│ │ └── acm/
│ │
├── .github/
│ └── workflows/
│ └── deploy.yml
│
├── README.md
└── LICENSE
各ディレクトリの役割
- hugo-site/:Hugoで生成する静的サイトのソース。Markdownで記事を書き、テーマでデザインを整える。
- terraform/:AWSリソース(S3, CloudFront, Route 53, ACM)をコードで管理。
- modules/:Terraformの構成をモジュール化することで再利用性と可読性を向上。
- .github/workflows/:GitHub ActionsでCI/CDを構成。記事更新 → 自動ビルド → S3へアップロード。
1. 静的サイトホスティング関連
リソース名 |
Terraformリソースタイプ |
用途 |
S3バケット |
aws_s3_bucket |
Hugoで生成した静的ファイルのホスティング |
S3バケットポリシー |
aws_s3_bucket_policy |
公開アクセス設定(静的サイト用) |
CloudFrontディストリビューション |
aws_cloudfront_distribution |
CDN配信、SSL証明書との連携 |
CloudFrontオリジンアクセスID |
aws_cloudfront_origin_access_identity |
S3への安全なアクセス |
2. ドメイン & DNS関連
リソース名 |
Terraformリソースタイプ |
用途 |
Route 53ホストゾーン |
aws_route53_zone |
ドメインのDNS管理 |
DNSレコード |
aws_route53_record |
A/AAAA/CNAMEなどのレコード設定 |
ドメイン登録情報(読み取り) |
aws_route53domains_registered_domain |
AWSで取得したドメインの登録情報を管理(※新規登録はTerraform不可) |
3. SSL/TLS証明書関連
リソース名 |
Terraformリソースタイプ |
用途 |
ACM証明書 |
aws_acm_certificate |
CloudFront用のSSL証明書(無料) |
DNS検証レコード |
aws_route53_record |
ACM証明書のDNS検証用レコード |
4. IAM関連
リソース名 |
Terraformリソースタイプ |
用途 |
IAMユーザー |
aws_iam_user |
TerraformやCI/CD用のアクセスユーザー |
IAMポリシー |
aws_iam_policy |
S3/CloudFrontなどへのアクセス権限 |
IAMポリシーアタッチメント |
aws_iam_user_policy_attachment |
ユーザーにポリシーを紐付け |
IAMアクセスキー |
aws_iam_access_key |
TerraformやGitHub Actionsで使用する認証情報 |
5. オプション(CI/CDやログ管理など)
リソース名 |
Terraformリソースタイプ |
用途 |
CloudWatchロググループ |
aws_cloudwatch_log_group |
CloudFrontやS3のログ管理 |
GitHub Actions用IAMロール |
aws_iam_role |
OIDC連携によるセキュアなCI/CD(高度な構成) |
GitHub Actionsで自動化
.github/workflows/deploy.yml(構成例)
name: Deploy Hugo Blog to AWS
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
env:
AWS_REGION: ap-northeast-1
S3_BUCKET: your-s3-bucket-name
CLOUDFRONT_DISTRIBUTION_ID: your-distribution-id
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: "0.121.1"
- name: Build Hugo site
run: hugo --minify
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Deploy to S3
run: |
aws s3 sync public/ s3://${{ env.S3_BUCKET }} \
--delete \
--acl public-read \
--cache-control "max-age=0, no-cache, no-store, must-revalidate"
- name: Invalidate CloudFront cache
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ env.CLOUDFRONT_DISTRIBUTION_ID }} \
--paths "/*"
この構成のポイント
- Hugoのビルドは hugo --minify で圧縮付きで生成。
- AWS認証情報は GitHub Secrets に登録して安全に管理。
- S3へのアップロードは aws s3 sync で差分更新。
- CloudFrontキャッシュの無効化で即時反映。
GitHub Secrets に登録すべき項目
名前 |
内容 |
AWS_ACCESS_KEY_ID |
IAMユーザーのアクセスキー |
AWS_SECRET_ACCESS_KEY |
IAMユーザーのシークレットキー |
Discussion