hexo を S3 でホスティングして Cloud Front で公開する。

このブログサイトを公開したときのメモです。

hexo を S3 でホスティングする

hexo で作成したコンテンツを S3 に置くには、 hexo-deployer-aws-s3 を使います。npm install hexo-deployer-aws-s3 --save-dev して、_config.yml ファイルに以下の記述を追加します。

1
2
3
4
5
deploy:
type: 'aws-s3'
region: S3 のリージョン
bucket: S3 のバケット名
prefix: S3 のフォルダ名

S3 バケットの「アクセス権限」設定を行います。「ブロックパブリックアクセス」を「オフ」にします。「オン」の状態だとデプロイに失敗します。

あとは、npm run build && npm run deploy でコンテンツが S3 に転送されます。

次に S3 の Static website hosting を有効にします。インデックスドキュメントは index.html、エラードキュメントは空でもいいですが、とりあえず index.html を指定しました。
また、ここに表示される「エンドポイント」は Cloud Front の設定で使用います。

サーバー証明書を取得

独自ドメインで HTTPS サイトを公開するために、サーバー証明書を取得します。AWS を使っているので Certificate Manager で証明書を取得します。
「証明書のリクエスト」ボタンを押すと、証明書のタイプを選択する画面になります。「パブリック証明書のリクエスト」を選択します。

ドメイン名を設定します。

「DNS の検証」を選択します。

タグは特に設定せず次のステップに進みます。

ドメイン名を確認して「確定とリクエスト」を押します。

DNS に設定するパラメータが表示されますので、これを DNS に登録します。

Cloud Front で公開する

Cloud Formation を使って、Cloud Front を立ち上げます。設定のポイントとしては

  • オリジンに S3 の Static website hosting のエンドポイントを指定する

これだけです。S3 バケットを指定すると、サブフォルダの index.html を解決できなくて 403 エラーになるページが発生します。

Cloud Formation テンプレートの例を示します。このテンプレートでは独自ドメインで hexo のコンテンツを公開することができます。HTTPS で公開するので Certificate Manager でリクエストした証明書の ARN を指定します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
AWSTemplateFormatVersion: 2010-09-09
Parameters:
BlogFQDN:
Description: FQDN for Blog
Type: 'CommaDelimitedList'
S3BlogBucketName:
Description: S3 Bucket Name for blog
Type: String
AcmCertificateArn:
Description: ACM Certificate ARN
Type: String

Resources:
BlogOriginAccessId:
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: 'Blog hosting'

BlogDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Aliases:
!Ref BlogFQDN
Comment: 'Blog site.'
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- OPTIONS
CachedMethods:
- GET
- HEAD
- OPTIONS
Compress: true
DefaultTTL: 86400
ForwardedValues:
QueryString: true
MaxTTL: 86400
MinTTL: 0
TargetOriginId: !Ref S3BlogBucketName
ViewerProtocolPolicy: 'redirect-to-https'
DefaultRootObject: 'index.html'
Enabled: true
HttpVersion: http2
IPV6Enabled: true
Origins:
- DomainName: !Sub "${S3BlogBucketName}.s3-website-us-east-1.amazonaws.com"
CustomOriginConfig:
OriginProtocolPolicy: http-only
Id: !Ref S3BlogBucketName
OriginPath: ''
PriceClass: 'PriceClass_All'
ViewerCertificate:
AcmCertificateArn: !Ref AcmCertificateArn
MinimumProtocolVersion: TLSv1.1_2016
SslSupportMethod: sni-only

このテンプレートを使って、以下のコマンドでスタックを構築します。

1
2
3
4
5
6
7
8
9
aws cloudformation deploy \
--region us-east-1 \
--stack-name [blog-site] \
--template-file cloud-front.yaml \
--capabilities CAPABILITY_IAM \
--parameter-overrides \
BlogFQDN=[公開するサイトの FQDN] \
S3BlogBucketName=[バケット名] \
AcmCertificateArn=[サーバー証明書の ARN]

これで、1時間待てばコンテンツを公開できます。