Cloudfront + S3 + Astroブログのサーバサイド設定
2023/04/16
![](/hp/articles/default.jpg)
EC2 + wordpressブログをCloudFront + S3 + Astroに移行したときのサーバ環境構築方法を紹介します。
1. S3バケットを作成する
まずはAstroブログを配置するためのS3バケットを作成します。自分のブログは日本人ターゲットのため、東京リージョンで作成しました。
S3でWebサイトを作る際は、いくつか設定を行う必要があります。
- 静的ウェブサイトホスティングを有効化 バケットのプロパティの「静的ウェブサイトホスティング」を有効化します。 これでエンドポイントが作られHTTPでアクセスできるようになります。 「ホスティングタイプ」は ”ホスティングタイプ” を選択します。
- インデックスドキュメントの設定 フォルダ指定でHTTPアクセスがあった場合に返却するファイル名を指定します。 「静的ウェブサイトホスティング」の設定画面の「インデックスドキュメント」項目で設定します。通常は”index.html”とします。
- アクセス許可(これはCloudFront作成後に設定する) ここが一番苦戦しましたが、CloufFront経由とするため「パブリックアクセスをすべて ブロック」はオンにします。 いろいろ試行錯誤して、最終的なアクセスポリシはこうなりました。 1つ目のStatementでcloudfrontからのアクセスを許可して、2つ目以降はaws cliコマンドからS3にブログを配信するための許可設定です。
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::astro-blog/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::xxxxxxxxxxxxx:distribution/XXXXXXXXXXXXX"
}
}
},
{
"Sid": "Stmt1546414471931",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxxxx:user/xxxxxxx"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::astro-blog"
},
{
"Sid": "Stmt1546414471931",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxxxx:user/xxxxxxx"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::astro-blog/*"
},
{
"Sid": "Stmt1546414471931",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxxxx:user/xxxxxxx"
},
"Action": "s3:DeleteObject",
"Resource": "arn:aws:s3:::astro-blog/*"
}
]
}
2. ドメインと証明書の用意
Cloudfrontを作成する前に利用するドメインと証明書を用意します。
元々ドメインはRoute53で購入していたのでそのまま利用します。証明書はLet’s encryptを利用していたのですが、これを機にACMで証明書を作成して切り替えました。
CloudfrontでACMの証明書を利用する場合は**「米国東部 (バージニア北部) リージョン」で証明書を作成する必要があります**。
ACMの証明書を有効にするためにDNS認証を行う必要があるため、Route53に検証用のCNAME名とCNAME値を登録して検証を行います。
3. CloudFrontの作成
cloudfrontのディストリビューションを作成します。
オリジンドメインは作成したS3を指定します。(astro-blog.s3.ap-northeast-1.amazonaws.com)
オリジンパスは空白のままにします。(/index.htmlを指定したら上手くいかなかった)
後、以下2点の設定を追加しています
- 下層ページでindex.htmlが表示されるようにする
- EC2(wordpress)とS3への振り分け(wordpressからの移行期間限定ですが)
3-1. 下層ページでindex.htmlが表示されるようにする
ここまでの設定でルートディレクトリへのアクセスはindex.htmlを読んでくれるのですが、下層のパスだとindex.htmlを読んでくれません。
【OK】 https://xxx.com/ →https://xxx.com/index.html
【NG】 https://xxx.com/aaa/ →https://xxx.com/aaa/index.html
これを実現するにはCloud関数を作る必要があります。以下の関数を作りビヘイビアのビューワーリクエストに紐づけます。これで解消します。
function handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith('/')) {
request.uri += 'index.html';
}
// Check whether the URI is missing a file extension.
else if (!uri.includes('.')) {
request.uri += '/index.html';
}
return request;
}
![img](/hp/articles/0148_s3-cf-astro-server/img1.png)
3-2. EC2(wordpress)とS3への振り分け
ビヘイビアを追加して、パスでEC2とS3への振り分けを行います。wordpressブログはパスが「/wordpress」から始まるようにしていたので、これをパターンにしました。
![img](/hp/articles/0148_s3-cf-astro-server/img2.png)
EC2で運用していた時は、EC2内のnginxまでhttpsだったのですが、CloudFrontとEC2の間はhttp通信になってしまいいろいろ不整合がでたので、「キャッシュキーとオリジンリクエスト」でOrigin、CloudFront-Forwarded-Proto、Hostヘッダを追加して対処しました。(これを行うと指定したヘッダ情報はCloudFrontへのリクエストから引き継がれます)
![img](/hp/articles/0148_s3-cf-astro-server/img3.png)