CloudFrontを久々に構築しましたが、UI変更や機能が追加されていたので、メモしておきます。
今回はS3オリジンで静的ファイル(SPAのNuxtアプリ)配信用で構築しています。
S3作成
コンテンツ用とログ用のバケットを作成します。
ログ用はACLを有効にしないとCloudFront作成時にエラーになります。後からでも変更できます。
> The S3 bucket that you specified for CloudFront logs does not enable ACL access: (バケット名).s3.amazonaws.com
コンテンツ用
https://s3.console.aws.amazon.com/s3/bucket/create?region=ap-northeast-1
バケットを作成 一般的な設定 バケット名: (ドメイン名) ※世界中で一致であれば何でも良いけど、解りやすいようにドメイン名にしました。 [バケットを作成]
ログ用
バケットを作成 一般的な設定 バケット名: logs-(ドメイン名) ※同様に世界中で一致であれば何でも良い。 オブジェクト所有者 ● ACL 有効 ● オブジェクトライター [バケットを作成]
<以降はデフォルトのまま>
後からACLを有効にする
CloudFront
ディストリビューション作成
ディストリビューションを作成 オリジン オリジンドメイン: (コンテンツ用のS3バケット) 名前: (自動で入るのでそのまま) S3 バケットアクセス ● Origin access control settings (recommended) Origin access control [コントロール設定を作成] Create control setting ● 署名リクエスト (推奨) [作成]● はい、OAI を使用します (バケットは CloudFront のみへのアクセスとなるように制限できます) オリジンアクセスアイデンティティ [新しい OAI を作成] バケットポリシー ● はい、バケットポリシーを自動で更新しますオリジンシールドを有効にする ● はい オリジンシールドリージョン アジアパシフィック (東京) ap-northeast-1 デフォルトのキャッシュビヘイビア ビューワープロトコルポリシー ● Redirect HTTP to HTTPS 許可された HTTP メソッド ● GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE HTTP メソッドをキャッシュ ■ オプション キャッシュキーとオリジンリクエスト ● Cache policy and origin request policy (recommended) ※S3のバケットポリシーに追加が必要 https://dev.classmethod.jp/articles/amazon-cloudfront-origin-access-control/ キャッシュポリシー: CachingOptimized(S3オリジンにおすすめ) ※キャッシュが長いので消さなくても良いようにポリシー作っても良い 例:CachingShort、最小TTL: 1、最大TTL: 5、デフォルトのTTL: 300 設定 料金クラス ● 北米、欧州、アジア、中東、アフリカを使用 代替ドメイン名 (CNAME) (ドメイン名) カスタム SSL 証明書 (ACMで作成するか作成した証明書を選択) デフォルトルートオブジェクト index.html 標準ログ記録 ● オン S3 バケット (ログ用のバケットを選択) [ディストリビューションを作成]
エラーページ設定
存在しないURLにアクセスするとAccessDeniedのXMLが表示されるので、S3に置いたHTMLが表示されるように設定を変えておきます。
エラーページ [カスタムエラーレスポンスを作成]
404かと思いきや、403でした。念の為、4xx系(400,403,404)すべて設定しました。
カスタムエラーレスポンスを作成 エラーレスポンス HTTPエラーコード: 400:Bad Request, 403: Forbidden, 404: Not Foundでそれぞれ設定 エラーレスポンスをカスタマイズ ●はい レスポンスページのパス: /404.html ※S3に設置したファイル HTTPレスポンスコード: 400:Bad Request, 403: Forbidden, 404: Not Foundでそれぞれ設定 [変更を保存]
500も設定しましたが、403になってしまう。急がないので別の機会に調べます。
→ 6. エラーページで設定したページが返却される
追記: Nuxtでトップ以外のURLを直打ちすると403になる
S3に対象のファイルが無いからですね。
403の時に/index.htmlに飛ばしてあげればOK
ただ、ステータスは、本当に無い時と区別が付かないので、200で設定するしかない。
カスタムエラーレスポンスを編集 エラーレスポンス HTTPエラーコード: 403: Forbidden エラーレスポンスをカスタマイズ ●はい レスポンスページのパス: /index.html HTTPレスポンスコード: 200: OK [変更を保存]
参考: CloudFront+S3環境上のSPA(Angular)で「/」以外のURLでリロードした場合に403(access denied)エラーとなる時の対処法 | DevelopersIO
ファイル設置
S3にファイル設置すれば完成。
今回の成果物: https://nuxtapp.nightonly.com/
awsコマンド使うと簡単ですね。
Nuxtアプリのパスで、ファイルを生成 % yarn generate ドライラン % aws s3 sync --dryrun --exact-timestamps --delete --exclude '.*' ./dist s3://nuxtapp.nightonly.com/ バケットに転送 % aws s3 sync --exact-timestamps --delete --exclude '.*' ./dist s3://nuxtapp.nightonly.com/
キャッシュ削除(無効リクエスト/invalidation)
キャッシュが効いているので、必要に応じて「キャッシュ削除」も忘れずに。
※短いTTLのキャッシュポリシーを作成・設定しておくと削除不要なので楽ですね。
キャッシュが効くので、大量アクセスにも対応できる。
メモ:Managed-Amplifyを設定したらエラーになりました。
キャッシュポリシーを作成 詳細 名前: CachingShort TTL設定 最小TTL: 1 最大TTL: 300 ※5分 デフォルトTTL: 300 [作成]
awsコマンドでやるならこんな感じ。
% aws cloudfront create-invalidation --distribution-id E1RYX6UROY72NN --paths "/*" { "Location": "https://cloudfront.amazonaws.com/2020-05-31/distribution/E1RYX6UROY72NN/invalidation/IT1IQA4V1L1O", "Invalidation": { "Id": "IT1IQA4V1L1O", "Status": "InProgress", "CreateTime": "2022-03-11T08:27:13.788000+00:00", "InvalidationBatch": { "Paths": { "Quantity": 1, "Items": [ "/*" ] }, "CallerReference": "cli-1646987232-669143" } } } ステータス確認 ※上記のIdも必要 % aws cloudfront get-invalidation --distribution-id E1RYX6UROY72NN --id IT1IQA4V1L1O { "Invalidation": { "Id": "IT1IQA4V1L1O", "Status": "Completed", "CreateTime": "2022-03-11T08:27:13.788000+00:00", "InvalidationBatch": { "Paths": { "Quantity": 1, "Items": [ "/*" ] }, "CallerReference": "cli-1646987232-669143" } } }
キャッシュ削除の料金
ちなみにキャッシュ削除は、月1,000パスを超えると有料です。
世界中のキャッシュサーバーに削除依頼をする為だと思われます。
月間で無効をリクエストしたパスの最初の 1,000 パスまでは追加料金なし。それ以降は、無効をリクエストしたパスごとに 0.005 USD かかります。
無効化パスを送信する料金は、無効にするファイルの数に関係なく同じです。つまり、1 つのファイル (/images/logo.jpg) であっても、ディストリビューションに関連付けられたすべてのファイル (/*) であっても同じです。
“CloudFront(S3オリジン)構築とawsコマンド(S3, CloudFront)メモ” に対して3件のコメントがあります。