Hugo+S3+CloudFrontで個人ブログを作る
目次
本稿では、Hugoで静的ブログサイトを作り、CloudFrontで配信する方法を紹介しています。
前半は、ブログコンテンツを作成するために使用しているHugoについて紹介しています。
後半は、Hugoで作成したブログコンテンツをS3にアップロードし、CloudFrontで配信する手順を紹介します。
全体像

上の図のようなアーキテクチャになります。
記事を執筆する際は、ローカルPCのHugoディレクトリで作業します。
Markdownで記事を執筆できます。
HugoにはローカルWebサーバ機能があるので、検証サイトを確認しながら記事を執筆できます。
記事が書けたら、コンパイルしてブログコンテンツを生成します。
生成されたブログコンテンツをS3にアップロードし、CloudFrontで配信します。
Hugoの設定方法
Hugoとは
公式ページ
Hugoは静的サイトジェネレータです。
Markdownで記事を書き、Hugoを実行すると、記事のページやTopページ、プロフィールページなどブログに必要なファイルを生成します。
これらのファイルをS3などに置けば簡単にブログを公開できます。
Hugoのインストール
Homebrewでインストールしました。
Mac以外の環境の場合は公式インストール手順ページに書いてあります。
$ brew install hugo
Hugoサイトを作成する
下記コマンドを叩くことでHugoサイトの雛形が生成されます。
$ hugo new site test-blog
下記のようなディレクトリと設定ファイルの一式が作成されます。
$ ls test-blog
.
├── archetypes # 記事のテンプレートを置くためのディレクトリ
│ └── default.md
├── content # 記事を置くためのディレクトリ
├── data # 記事で使用したいパラメータを置くためのディレクトリ(toml、yaml、json)
├── hugo.toml # 設定ファイル
├── layouts # themeの上書きや独自レイアウトを追加するためのディレクトリ
├── static # 静的ファイルを置くためのディレクトリ
└── themes # テーマを入れるためのディレクトリ
Hugoサイトの雛形へ移動して、
$ cd test-blog
Gitで管理します。
$ git init
$ git add .
$ git commit -m "first commit"
使用するテーマを設定する
https://themes.gohugo.io/themes/
Hugo公式ページでは、さまざまなテーマが紹介されているので、このページから使用したいテーマを選ぶことができます。
今回はhugo-blog-awesomeを使用します。
git submodule addコマンドを叩くことで、themesの配下にhugo-blog-awesomeテーマを追加します。
$ git submodule add https://github.com/hugo-sid/hugo-blog-awesome.git themes/hugo-blog-awesome
設定ファイルは、test-blog/hugo.tomlを開いて
$ vim hugo.toml
下記のように更新します。
baseURL = 'http://example.com/'
languageCode = 'ja-jp'
title = 'My New Hugo Site'
theme = 'hugo-blog-awesome'
defaultContentLanguage = 'ja'
[Languages]
[Languages.ja]
languageName = "Japanese"
languageCode = "ja"
contentDir = "content"
weight = 1
[Languages.ja.menu]
[[Languages.ja.menu.main]]
pageRef="/"
name = 'ホーム'
url = '/'
weight = 10
[[Languages.ja.menu.main]]
pageRef="posts"
name = '投稿'
url = '/posts/'
weight = 20
[Languages.ja.params.author]
intro = "サイト名"
name = "author"
description = "これはテストブログです"
| 設定項目 | 設定する内容 |
|---|---|
| baseURL | 公開するときのURL |
| languageCode | 言語設定 |
| title | ブログタイトル |
| theme | 使いたいテーマ名 |
| defaultContentLanguage | デフォルトで表示する言語ページ |
| Languages | 各言語ページ毎の設定 |
| Languages.ja.menu | 日本語ページで表示するメニューの設定 |
| Languages.ja.prams | 日本語ページで使用するパラメータの設定 |
| Languages.ja.params.authorのintro | サイト名※ |
| Languages.ja.params.authorのname | 執筆者名※ |
| Languages.ja.params.authorのdescription | サイト説明※ |
hugo-blog-awesomeでは言語毎のページを作成できますが、今回は日本語ページのみの設定を行っています。
※ hugo-blog-awesomeのデモを見るとLanguages.ja.params.authorで執筆者情報を表示していますが、私はこれをサイト名表示に使用しています。
コンパイルする
下記コマンドを実行することで、Markdownで記載した記事をブログコンテンツにコンパイルします。
$ hugo --minify
–minifyオプションを使うことで、出力される HTML / CSS / JS ファイルを圧縮できます。
このコマンド実行後、publicディレクトリが作成され、この中にブログコンテンツが置かれます。
.
├── archetypes
│ └── default.md
├── content
├── data
├── hugo.toml
├── layouts
├── static
├── public # new
└── themes
ローカルサーバーで確認する
HugoはローカルWebサーバ機能を内蔵しているので、下記コマンドで立ち上げます。
このコマンドを実行すると、記事がコンパイルされてから、ローカルWebサーバが立ち上がります。
$ hugo serve -D --minify
-Dオプションは下書き(draft=true)ページを表示するオプションです。
立ち上げたローカルサーバ(http://localhost:1313/ )にアクセスすると、ブログトップページにアクセスできます。

以上がHugoのインストール方法と設定方法でした。
次はこれをS3に上げてCloudFrontで配信するために、AWSコンソールでの設定を行います。
S3バケットの作成
まずはブログコンテンツを配置するS3バケットを作成します。
デフォルトの設定で大丈夫です。
ブログurlをhttps://blog.<ドメイン名>にしたいので、わかりやすいようにバケット名もこのように設定しました。
下記コマンドでs3バケットにブログコンテンツをアップロードします。
$ aws s3 sync --delete public/ s3://<バケット名>
–deleteオプションは、publicフォルダに存在せずs3バケットに存在するファイルを削除するオプションです。
CloudFrontの作成、設定
次にCloudFrontディストリビューションを作成します。
名前と説明のところはわかりやすくブログFQDNにしています。
custom domainの設定はスキップします。
オリジンドメインは先ほど作成したS3バケットを選択します。
Settingはデフォルトで大丈夫です。
WAFの設定はOFFで作ります。
その後確認画面がでるので、確認してCloudFrontディストリビューションを作成します。
デフォルトルートオブジェクトの設定
次に、https://blog.<個人ドメイン名>にアクセスしたら、https://blog.<個人ドメイン名>/index.htmlにアクセスする設定をします。
CloudFrontディストリビューションの設定を編集して、
index.htmlをデフォルトルートオブジェクトに設定します。
パスの設定
次に、URLの末尾が"/“のURL(https://blog.<個人ドメイン名>/posts/article1/)にアクセスしたとき、末尾がindex.htmlのURL(https://blog.<個人ドメイン名>/posts/article1/index.html)に変更する設定をします。
下記のようなコードでCloudFront Functionを作成します。
ランタイムはcloudfront-js-2.0で作成します。
function handler(event) {
var request = event.request;
var uri = request.uri;
if (uri.endsWith('/')) {
request.uri += 'index.html';
}
else if (!uri.includes('.')) {
request.uri += '/index.html';
}
return request;
}
その後、“関数を発行"ボタンを押して関数を発行します。
発行できたら、“関連付けを追加"ボタンを押して、先ほど作成したCloudFrontディストリビューションのDefaultビヘイビアのView Requestと関連づけます。

アクセス確認
最後に、CloudFrontディストリビューションのページから、ディストリビューションドメイン名をコピーして、ブラウザからアクセスできるかチェックします。


ブログにアクセスできれば成功です。
ドメインの設定
ドメインの購入
ブログサイトへのアクセスをHTTPSで行うために、個人ドメインが必要です。
Route53で購入します。
マネジメントコンソールでRoute53を開いたら、登録済みドメインから、“ドメインを登録ボタン"でドメイン購入ページへアクセスできます。
ブログサイト用サブドメインの設定
購入したドメインを使用して、ブログサイト用のドメインを作成します。
Route53の左ペインのホストゾーンをクリックして、先ほど登録したドメイン名が存在することを確認します。

ブログ用に新しいホストゾーンを作成します。
ブログ用サブドメイン : blog.<購入したドメイン>
作成したレコードを開くと下の画像のようにレコードが2つできています。
上の図の赤い四角の中に4つアドレスがあるので、これをコピーします。
次に購入したドメイン名と同じホストゾーンを開き、NSレコードを作成します
このレコードの値に先ほどコピーした4つのアドレスをペーストします。
- レコード名: blog
- レコードタイプ: NS - ホストゾーンのネームサーバ
- 値: 先ほどコピーした4つのアドレス
証明書の作成
サーバ証明書をACMで作成します。
証明書タイプはパブリックで作成します。
下記2つのURLでブログサイトにアクセスするように設定するので、下記のように2つドメインを登録します。
https://blog.<購入したドメインhttps://www.blog.<購入したドメイン>
リクエストボタンを押すと、検証ページに遷移するので、“Route53でレコードを作成"ボタンを押します。

検証ページの証明書ステータスが"保留中の検証"から"発行済み"に変われば成功です。
CloudFrontの代替ドメイン設定
次にCloudFrontディストリビューションの設定を編集して、代替ドメイン名にブログサイト用ドメインを追加します。
CloudFrontの設定の代替ドメイン名のところにある"Add domain"ボタンをクリックします。
下記2つのドメインを追加します。
https://blog.<購入したドメインhttps://www.blog.<購入したドメイン>
次のGet TLS certificateページでは、先ほど作成した証明書が表示されているので、そのまま何もせず次に進みます。
ブログサイト用レコードの設定
次にブログサイト用のAレコードを作成します。
ブログサイト用サブドメインに下記2つのAレコードを登録します。
https://blog.<購入したドメイン- レコード名: 空白
- レコードタイプ: A - IPv4アドレスと一部のAWSリソースに…
- エイリアス: True
- トラフィックのルーティング先
- CloudFrontディストリビューションへのエイリアス
- CloudFrontディストリビューションID
https://www.blog.<購入したドメイン>- レコード名: www
- レコードタイプ: A - IPv4アドレスと一部のAWSリソースに…
- エイリアス: True
- トラフィックのルーティング先
- CloudFrontディストリビューションへのエイリアス
- CloudFrontディストリビューションID
アクセス確認
最後に、下記2つのURLをブラウザに入力し、ブログサイトへアクセスできるかチェックします。
https://blog.<購入したドメインhttps://www.blog.<購入したドメイン>
運用方法
記事を執筆する
hugoディレクトリに行き、下記コマンドを叩くことで記事を書くためのmarkdownファイルが生成されます。
$ hugo new posts/my-first-post/index.md
$ tree .
.
├── ...
├── content
│ └── posts
│ └── my-first-posts
│ └── index.md # 追加されていることを確認
contentディレクトリの中に記事を書くためのMarkdownを追加していきます。
postsディレクトリをブログ記事のディレクトリとしています。
my-first-postsディレクトリを"はじめてのHugo"という記事のディレクトリとしています。
index.mdが記事を書くためのMarkdownファイルです。
“はじめてのHugo"という記事で画像を使用したい場合、my-first-postsディレクトリに画像ファイルを追加することで、Markdownの書式で画像を使用できます。
追加されたMarkdownファイルに執筆していきます。
$ vim content/posts/my-first-post/index.md
設定項目が付いているので、まずはこれを編集します。
+++
title= "はじめてのHugo"
date= 2023-06-17T14:06:00+09:00
draft= true
toc= true
+++
| 設定項目 | 設定する内容 |
|---|---|
| title | ページのタイトル |
| date | 日付 |
| draft | 下書きページかどうか |
| toc | 目次を表示するかどうか |
設定項目の下は記事の本文を書く部分になります。
+++
title= "はじめてのHugo"
date= 2023-06-17T14:06:00+09:00
draft= true
toc= true
+++
# はじめてのHugo
## Hugoとは
Golangで書かれたSSG
## Hugoを使ってみた感想
良き
記事を確認する
HugoはローカルWebサーバを内蔵しているので、下記コマンドで立ち上げます。
$ hugo serve -D --minify
立ち上げたローカルサーバ(http://localhost:1313/ )にアクセスすると、ブログトップページにアクセスできます。
記事が追加されたことを確認します。
記事タイトルをクリックすると、記事を閲覧できることを確認します。

記事を公開する
下記コマンドで、記事をコンパイルします。
$ hugo --minify
下記コマンドで、s3バケットにブログコンテンツをアップロードします。
$ aws s3 sync --delete public/ s3://<バケット名>
下記コマンドで、CloudFrontのキャッシュを削除します。
$ aws cloudfront create-invalidation --distribution-id <CloudFrontディストリビューションID> --paths "/*"