ぬまろぐ

←戻る

Cloudfront + S3 + Astroブログのサーバサイド設定

2023/04/16

EC2 + wordpressブログをCloudFront + S3 + Astroに移行したときのサーバ環境構築方法を紹介します。

1. S3バケットを作成する

まずはAstroブログを配置するためのS3バケットを作成します。自分のブログは日本人ターゲットのため、東京リージョンで作成しました。

S3でWebサイトを作る際は、いくつか設定を行う必要があります。

  1. 静的ウェブサイトホスティングを有効化 バケットのプロパティの「静的ウェブサイトホスティング」を有効化します。 これでエンドポイントが作られHTTPでアクセスできるようになります。 「ホスティングタイプ」は ”ホスティングタイプ” を選択します。
  2. インデックスドキュメントの設定 フォルダ指定でHTTPアクセスがあった場合に返却するファイル名を指定します。 「静的ウェブサイトホスティング」の設定画面の「インデックスドキュメント」項目で設定します。通常は”index.html”とします。
  3. アクセス許可(これは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点の設定を追加しています

  1. 下層ページでindex.htmlが表示されるようにする
  2. 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

3-2. EC2(wordpress)とS3への振り分け

ビヘイビアを追加して、パスでEC2とS3への振り分けを行います。wordpressブログはパスが「/wordpress」から始まるようにしていたので、これをパターンにしました。

img

EC2で運用していた時は、EC2内のnginxまでhttpsだったのですが、CloudFrontとEC2の間はhttp通信になってしまいいろいろ不整合がでたので、「キャッシュキーとオリジンリクエスト」でOrigin、CloudFront-Forwarded-Proto、Hostヘッダを追加して対処しました。(これを行うと指定したヘッダ情報はCloudFrontへのリクエストから引き継がれます)

img