たくさんの自由帳
Androidのお話
たくさんの自由帳
投稿日 : | 0 日前
文字数(だいたい) : 15797
目次
本題
ほかを探す
AWS
AWS で静的サイトホスティングするには
CloudFront + S3 も二通りある
S3 の静的ホスティング機能を使う
S3 の静的ホスティング機能を使わない
つくる!!
ながれ
S3 のバケットを作る
S3 にファイルを置く
CloudFront のディストリビューションを作る
カスタムドメインと HTTPS 化
DNS のレコードを追加する
CloudFront Functions を書く
GitHub Actions で S3 へアップロードし、CloudFront のキャッシュを消す
AWS 側
GitHub 側
デプロイ結果
エラー時の代わりのページの設定
ところで
DNS の向き先をホスティングサービスから CloudFront に直す
おわり!!!
ソースコード
速度
お金がかかるポイント?
おわりに
おわりに2
おわりに3 2023/12/26 追記
どうもこんにちは。
コイバナ恋愛 攻略しました。めっちゃおもろかったです
特に共通ルート面白い!!男友達とバカやってるのがいい。
髪下ろしてるのかわいい
個別みじかい!!!ただでさえ短い個別がサブカプに取られてて更に短くなってる気がする;;
(でもサブカプの話も面白かった)
(ところでこの手の途中下車パターン(?)ってセーブして先に共通全部見るのがいいのかな、どうなんだろう)
おすすめです!
このブログは Netlify にあるわけですが、読み込みが遅い・・・
原因は日本にはCDNが無いらしく?(今もなはず?2020年から速度変わってない気がするんだよな)、日本からアクセスだとちょっと遅い。
個人の感想 + 昔使ったことがあるとかで今は知らない ので参考にしてはいけない。
静的ファイルホスティングなので、SSRとかしたい場合知らないです
APEXドメイン使いたい場合はドメインのCDNをCloudflare DNSにしないといけないぐらいしか欠点がなさそう感Next.js 作ってる会社
Next.jsの一部の機能(next/imageとか)はVercelかレンタルサーバーで Node.js を動かすのどっちかが必要だったはずで、NetlifyのノリでNext.js全部の機能を使いたければこれが良さそう
index.htmlが入ってるフォルダをドラッグアンドドロップすればデプロイ出来る機能とかが便利だった
Cloudflare Pagesにもある(小声)/docsにするか、ルートに置くかFirebaseのプロジェクト作るのアレじゃない・・・
FCMとか使ってるならいいんじゃない?CLI経由でデプロイした気がするけど、いまもCLI経由しか無いんですかね?こんなかんじ(めっちゃ個人的というか偏ってるな)
うーんCloudflare Pagesかなあ
そういえばお一人様 MisskeyのためにAWSのLightsail や S3を使っているわけですが
すでにAWS使ってるならこのサイトもAWSに乗せていいのでは・・!
料金もお一人様を動かす費用から見たらたいしたことないはず。。です
(後なんかAWSで動かしてるのなんかかっこいいじゃん)
二択あるらしい
前者のAmplifyだと、CI/CD機能が標準であったりして簡単に倒していそう、
ただ、転送量の無料枠、CloudFrontよりも低く設定し過ぎじゃない・・・?
後者のCloudFront + S3を使う方法だと、2つのサービス(正確にはもうちょっとある)を使う必要がある、CI/CDを自前で用意する必要がある
が、GitHub Actionsすでにあるし、何と言っても無料枠もCloudFrontのほうがあるのでこっちで!
どっちも一長一短で、難しい
S3の静的サイトホスティング機能を有効にして、CloudFrontを経由してアクセスするようにする
S3単体だとhttpsに出来ないので、CloudFrontを噛ますようにします、他にもキャッシュしてくれるのでS3の静的サイトホスティングは利用しないで、CloudFrontからリクエストが来たらS3から取り出す
CloudFront Functionsを利用する必要があります前者のS3 静的サイトホスティングの方法が簡単ですが、アクセスをCloudFront限定にすることが出来ません。S3の静的サイトホスティング用のURLがバレた(あるのかな・・)場合、S3にアクセスできてしまいます。
(CloudFrontを噛ますことでキャッシュを返してくれて、S3へのアクセス料金が安くなるのですが、S3に直接アクセスされると料金が安くならない!)
後者はS3からとってくるのはCloudFrontしか出来ないので、アクセスをCloudFrontだけに出来ます。
一方、S3の静的サイトホスティング機能の一つに、インデックスドキュメント機能というのが存在し、これは/や/about等にアクセスが来た際に自動的にindex.htmlをレスポンスとして返してくれるのですが、
この機能はCloudFrontにはなく、/aboutにアクセスされてしまった場合403? 404?になってしまいます。
何もしない場合は/about.htmlや/about/index.htmlみたく、index.htmlまでURLを書かないと正しく表示できません。
CloudFront Functionsという、リクエストが来た際にindex.htmlをURLに足すようなJavaScriptコードを書くことで実現出来ます。JavaScriptを書くと言っても、既にサンプルがあるのでこれをコピーするだけだと思います。CloudFront Functionsは一ヶ月200万リクエストまでは無料で出来るので、多分この規模なら超えることはない・・・ハズ?
でどっちを使うかなんですが、後者を試してみようと思います。
直接アクセスはやっぱされたくないかなー・・・
S3のバケットを作るS3 にファイルを置く
CloudFrontのディストリビューションを作る
OACでS3をオリジンとして利用できるようにCloudFrontでドメインとHTTPS化を行うCloudFront Functionsを書くGitHub Actionsでgit push時にS3にアップロードとCloudFrontのキャッシュクリアCloudFrontにする(CNAMEの値をCloudFrontにして、リクエストがCloudFrontに向くようにする)S3のバケットを作ります、名前はおまかせします。
東京リージョンでいいはずですが、CloudFrontを経由させるので本当に金払いたくなければ安いところでいいんじゃね?知らんけど
その他の設定は変えずに、作ります!
が、この時点でNext.jsのSSGをして公開するファイルを生成するのは面倒なので、適当に確認用のindex.htmlを書いてアップロードします
ところでVSCodeで!を書いた後にエンターを押すとhtmlのひな形みたいなのが出てくるんですけど、これVSCodeの標準機能なんですかね?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>てすと</title>
</head>
<body>
あいうえお
</body>
</html>S3の画面へドラッグアンドドロップすればアップロード出来ます
CloudFrontに移動して、ディストリビューションを作成を押します
オリジンはさっき作ったS3のバケットを選びます。
ドロップダウンメニューで選べるので入力しなくて済むはず
次はオリジンアクセス、これはOrigin access control settings (recommended)を選び、
コントロール設定を作成を押して作成画面を開きます
多分デフォルトで作成すればいいはず、説明とかはおまかせします。
この警告はディストリビューション作成後に対応するので一旦飛ばします。
次はWAFですが、よくわからないので無効にしておきました。
これで作成を行います!
そしたら上の方に案内が出ているので、ポリシーをコピーしてS3 バケット~のリンクを開きます。
そしたら、バケットポリシーの項目までスクロールして、編集を押します
エディターが表示されるので、さっきコピーした内容を貼り付けて変更の保存を押します。
そしたらCloudFrontに戻ってきてください。アクセスできるか確認しますディストリビューションドメイン名をコピーして、後ろに/index.htmlをつけてリクエストしてみます。
どうでしょう?index.htmlが表示されましたか?
ちょっとそれますがCloudFrontから帰ってきた場合、CloudFront側のキャッシュが帰ってきたのか、キャッシュもなくS3からとってきたのかはレスポンスヘッダーから見ることが出来ます。
一回目はMiss from cloudfront、二回目以降はHit from cloudfrontが帰ってくるはず。
C:\Users\takusan23>curl -I https://{ディストリビューションドメイン名}/index.html
HTTP/1.1 200 OK
Content-Type: text/html
Server: AmazonS3
X-Cache: Miss from cloudfront
C:\Users\takusan23>curl -I https://{ディストリビューションドメイン名}/index.html
HTTP/1.1 200 OK
Content-Type: text/html
Server: AmazonS3
X-Cache: Hit from cloudfront既にhttpsですが、カスタムドメインを設定する際にhttps周りの作業が必要なので・・
CloudFrontのディストリビューションを開いて、編集を押します。
代替ドメイン名という項目があるので、項目を追加を押します
はい
これで変更を保存しようとすると、、、出来ません。
To add an alternate domain name (CNAME) to a CloudFront distribution, you must attach a trusted certificate that validates your authorization to use the domain name. For more details, see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-requirementsカスタム SSL 証明書 - オプションの項目もやらないといけないようです。
というわけでスクロールして戻って、証明書をリクエストを押します
AWS Certificate Manager (ACM)が開くはず、CloudFrontで使う証明書はリージョンがバージニア北部である必要があるのでちゃんと確認しましょう。
パブリック証明書をリクエストで次へ
完全修飾ドメイン名はhttps://こ↑こ↓/index.htmlの部分です、FQDNとかかっこいい名前がついてる
サブドメインじゃない場合はどうなんだろう・・・
検証方法はDNSでいいはず
その他の項目はそのままにして、リクエストを押します
すると上の方に、追加のアクションが必要ですみたいなのが出てくるので、証明書を表示を押します。
ちょっとスクロールすると、ドメインの項目でCNAME 名、CNAME 値が表示されているはず。
この値を使ってドメインを持っていることを証明します。
私はドメインのDNSにCloudflare DNSを使っています。
が、別に特別なことはしてないので操作は大体同じだと思います。
Cloudflareにログインした後、ドメイン名を押してDNSを開いて、レコードを追加する画面を出します。
タイプはCNAMEにして、名前にはCNAME 名、値にはCNAME 値をそれぞれ入れます。
入力の際に一番最後の.が消えちゃいますが特に問題なかったです。
Cloudflareの場合は追加でProxyするか選べますが、別にユーザー公開するやつじゃないのでProxyするまでもないはずなのでチェックを外してDNS Onlyにします。
あとはAWS側で証明が終わるまで待ちます。
終わるとこんな感じにチェックマークが付きます
あとはCloudFrontのディストリビューション設定に戻って、さっき作った証明書を設定します。
これでようやく設定が変更できました。
あ、あとリージョンを元の(多分?東京)に戻しておいてね、多分戻ってると思うけど
こうすることで、https://takusan.negitoro.dev/index.htmlみたいなURLをhttps://takusan.negitoro.dev/みたいにindex.html省略してリクエストできるようにします。
↓ 以下現状
CloudFrontから関数を選び、関数を作成を押します。
いい感じの名前をつけます、説明はお任せ
JavaScriptのコードは以下のものを使うことにします。書いたら変更の保存して、
発行を押します
そしたら関連付けを追加を押して
埋めます。
CloudFrontを選ぶViewer requestを選ぶdefault?関連付けを追加を押します。
なんか時間かかってるけど待ちます
成功していれば、index.html無しで開けるようになっているはずです!

GitHub Actions で OIDC を使用して AWS 認証を行う
https://zenn.dev/kou_pg_0131/articles/gh-actions-oidc-aws

アマゾン ウェブ サービスでの OpenID Connect の構成 - GitHub Docs
https://docs-internal.github.com/ja/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-aws
さて、二日目に突入しました、がんばりますGitHub Actionsにビルドしてもらって成果物をS3にアップロードして、CloudFrontが持っているキャッシュを消す作業をしてもらいます。
調べてみるとOpenID Connectのほうがいいらしいので、今回はアクセスキーじゃなくてこっちを使ってみる。
アクセスキーだとGitHubへ機密情報(アクセスキー)を登録しないといけないのに対し、OpenID Connect (OIDC)だとGitHubへ機密情報を渡すこと無く同様のことが出来るらしい
まずはIAMの管理画面へ進み、ID プロバイダを押して、プロバイダを追加を押す
そしたら以下の項目を埋めます
https://token.actions.githubusercontent.comsts.amazonaws.com埋めたらサムプリントを取得を押します、押したらなんか出ます、、がそのままスクロールしてプロバイダを追加を押して閉じます
完了したら、上の方にIAM ロールを追加しろと出るので、追加します。ロールの割り当てを押しましょう
新しいロールの作成、でいいはず
ラジオボタンはウェブアイデンティティを選びます。
以下を埋めます(各自違うはず)
ブランチも制限出来るらしいですがとりあえずこれで。
次は許可する権限を設定する画面です。
多分独自のポリシーを作らないといけないはず・・(読み取り権限を指定したS3 バケットに付与、みたいな)
がとりあえず今回はAmazonS3FullAccessとCloudFrontFullAccessを付けました、多分指定したリソース(S3バケット、CloudFront ディストリビューション)だけにアクセスできるようにするのがお作法な気がする
そしたら次へ進み、名前と説明をいい感じに入れてロールを作成を押します
これで完了。次はGitHub Actionsを書いていきます。
まずは必要な値をGitHubのシークレットに登録します!
アクセスキーは登録する必要がなくなりましたが、S3 のバケット名とかCloudFrontのディストリビューション名とかは隠さないといけないので・・・
GitHubのリポジトリの設定画面から、Secrets and variablesを押して、Actionsを押すNew repository secretを押して、追加画面を出します
シークレットに登録する値は以下の4つです。
(後述するGitHub Actionsのymlをまるまるコピーする場合)
| なまえ | あたい |
|---|---|
| AWS_ROLE | IAM ロールの ARN の値です。コピーしてね ![]() |
| AWS_REGION | リージョンです、多分東京 ap-northeast-1 でいいはず? |
| AWS_S3_BACKET | ビルド成果物を保存するS3 バケットの名前です |
| AWS_CLOUDFRONT_DISTRIBUTION | CloudFrontのディストリビューションIDです、ID の列に出てるやつ |
出来ました!
次はGitHub Actionsを書いていきます、Actionsを開きます。既に一個あるので、ここから追加します
一個もない場合は多分こっちの画面が最初から出ると思う。set up a workflow yourselfを選びます
そして以下のようなymlを書きます。
ビルド成果物のフォルダが./outじゃない場合は直してください。
s3 sync --deleteを使うとローカルとS3バケットの中身が一緒になるように同期してくれるそうです!すごい
CloudFrontのキャッシュも消します。/*で一括削除です。キャッシュクリアは回数制限がありますが無料で出来ます。# ビルドして成果物を Amazon S3 にアップロードして、CloudFront のキャッシュを消す
# 名前
name: AWS Deploy
# 起動条件。pushと手動起動
on:
push:
workflow_dispatch:
# OpenID Connect
permissions:
id-token: write
contents: read
# やらせること
jobs:
build:
# OS
runs-on: ubuntu-latest
steps:
# リポジトリをクローン
- name: Clone repository
uses: actions/checkout@v2
# AWS の認証を行う
- name: Setup aws credentials
uses: aws-actions/configure-aws-credentials@v3
with:
role-to-assume: ${{ secrets.AWS_ROLE }}
aws-region: ${{ secrets.AWS_REGION }}
# Node.js インストール
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 20.9.0
# 依存関係
- name: Package install
run: npm i
# 書き出し
- name: Build page
run: npm run deploy
# Amazon S3 のバケットにアップロード
- name: Upload S3 backet
run: aws s3 sync --delete ./out s3://${{ secrets.AWS_S3_BACKET }}
# CloudFront のキャッシュを消す
- name: Clear CloudFront cache
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CLOUDFRONT_DISTRIBUTION }} --paths "/*"さて!待ちます。
無事一発で通りました、逆に心配で草
S3 のバケットもみてみましたが、ちゃんと中身あります!
開いてみましたが、めっちゃ早い気がする!いや気がするじゃなくて実際早い!!!なにこれ!!!CloudFrontまじ早くない?Next.jsももちろん早いんだけど
このままだと存在しないURLにアクセスされた際に、/404/index.htmlではなくAWS側のエラー画面が出てしまいます。
というわけで、S3にもなかった場合は404ページをブラウザに返してあげるようにCloudFrontを設定します。
この構成(Amazon S3 + CloudFront)で存在しないパスにアクセスすると、404ではなく403になります。
何でかはよく知りませんが、この辺がそう?
話を戻して、エラー画面を返す方法ですが、CloudFrontのディストリビューションを開いて、エラーページを開き、カスタムエラーレスポンスを押します。
先述の通り、存在しない場合にS3側は403を返すので、HTTP エラーコードは403を選びます。Next.jsの場合、trailingSlash: trueの場合は/404/index.html、falseの場合は多分/404.htmlで404 画面に飛ばせるはず。
ステータスコードは404で返しておきます。
しばらく待ちます
これで、エラーページが返ってくるようになりました。
私も勘違いしてましたが、これはリダイレクトではなく、エラー内容をCloudFront側で変更しているだけなので、ブラウザのアドレス欄はそのままになります。
まずCloudFrontのディストリビューションを開いてディストリビューションドメイン名をコピーします
そのあと、使ってるドメインのDNSの管理画面で、向き先を変えます(新規サイトの場合は追加します)CNAMEで、名前は使いたいサブドメインを入れて(APEXドメインは知らない)、値にはさっきのディストリビューションドメイン名を入れます
後は暫く待つと、サブドメインでアクセスできるようになってるはずです。httpsなのでちゃんと鍵マークも付いてるはず!
ながい!!!お疲れ様です・・・
参考にした記事ありがとうございます
GitHub Actionsのワークフローだけあったところでではありますが、、一応置いておきますziyuutyou-next/.github/workflows/aws-deploy.yml at main · takusan23/ziyuutyou-next
たくさんの自由帳の中身。自作ブログ。Next.js と Tailwind CSS と Unified でできている。 - takusan23/ziyuutyou-next
https://github.com/takusan23/ziyuutyou-next/blob/main/.github/workflows/aws-deploy.yml
早くなってる!
S3 - CloudFront の間のリクエスト回数
CloudFrontが間に入ってキャッシュするのでそこまでで
GETリクエストは他と比べれば高くないGitHub Actions から S3 にアップロードする
AWSに入ってくる通信は無料だけど、PUTリクエストの課金はかかってしまう
CloudFront FunctionsCloudFront の転送量は1TBまで無料なので超過はまず無いはず
CloudFront Functions はリクエスト回数のたびに呼ばれるので、ちょっと心配かも
Next.jsはページ表示に複数のjsファイルをリクエストするので、1ページに複数回リクエストになってしまうくらい?
お金問題なければこれで行きたいかも。
しれーっと切り替わってるかもしれない。一応戻せるようにしばらくはNetlifyのGitHub Actionsも動かしとこうかな。
もう誰も読んでないと思うけど
冒頭のゲームの話なんですけど(本題関係ない)、デフォルトのフォントがモトヤマルベリで、なんかすごい懐かしい気分になった。丸い感じすき
というのもAndroid 4 ~ 5の標準日本語フォントがモトヤマルベリだったんですよね、なんでもAOSPのためにApache Licenseの元使えるようにしたとかなんとか
だた、Galaxy / Xperia / arrows / AQUOS Phone あたりは独自フォントのはずなので(めっちゃ頑張ればフォントだけでおおよそのメーカーが見分けられそう)、Nexus 系列(まだ Nexus の頃)を買わないと見る機会はなかったのかもしれない?
このゲームのreadme.txt開いたらAOSPのライセンス(Apache License 2.0)あったけどもしかしてフォントのことだったのかな。
2023年 12月 から試しにCloudFrontからこのブログを配信しています。特に問題は無さそう感。
C:\Users\takusan23>curl -I https://takusan.negitoro.dev/
HTTP/1.1 200 OK
Content-Type: text/html
Server: AmazonS3
X-Cache: Hit from cloudfront