【React】【Terraform】CloudFront+S3へデプロイしてアクセスできるようにする
React アプリを AWS へデプロイし、WEB ブラウザからアクセスしてみます
最近勉強しているTerraform を使用して AWS の環境を構築していきます
ゴール
(インフラ構成図)

(ポイント)
- React アプリを S3 にデプロイする
- HTTPS 通信を実現するために CloudFront を S3 の前に置く
- CloudFront 経由でのみ、アプリ用 S3 にアクセス可能
- Route53 を使用し、独自ドメインでアクセスする
- ACM を適用し、HTTPS で通信する
前提
- Terraform、AWS CLI が使える環境にある
- IAM ユーザーは Administrator
-
使用するドメインを取得し、Route53 で管理している
- まだの方はこちらの記事をご参考ください
-
react のプロジェクトを作成できる
- まだの方はこちらの記事をご参考ください
構築のざっくりとした流れ
- Terraform で AWS 環境を構築する
- React アプリを作成する
- 2. で作成したアプリを S3 にデプロイする
- WEB ブラウザからアクセスする
やってみる
Terraform で AWS 環境を構築する
ソースコード
詳細はリポジトリ内の README やソースコード内のコメントをご覧ください
AWS に環境構築する
// tfファイルのあるディレクトリに移動しておく
1. terraform init
2. terraform plan
3. terraform apply -auto-approve
(構築完了まで5分ぐらいかかりました。。。)
終了したら、AWS コンソールから確認してみましょう!
S3, CloudFront, Route53, ACM にリソースが作成されていれば OK です!
HTML ファイルを S3 において動作確認する
まずは、PC 内の適当な場所にindex.html を作成します
今回は Desktop 配下の「app_to_S3」というフォルダ内に作成します
// 使用するコマンドはLinux
// Desktopに移動しておく
Desktop$ cd app_to_S3/
app_to_S3$ touch index.html
index.html の中身は以下。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>index.html</h1>
</body>
</html>
次にS3 に AWS CLI を使ってアップロードしていきます
アプリ用のバケットは「hisui-react-app-bucket」なので、コマンドはこんな感じ
// 対象S3の確認
app_to_S3$ aws s3 ls
2023-06-14 22:19:10 hisui-cloudfront-log-bucket
2023-06-14 22:19:10 hisui-react-app-bucket
// S3へアップロード
app_to_S3$ aws s3 cp index.html s3://hisui-react-app-bucket/
upload: ./index.html to s3://hisui-react-app-bucket/index.html
// S3の中身を確認
app_to_S3$ aws s3 ls s3://hisui-react-app-bucket/
2023-06-14 22:54:53 273 index.html
https://<CloudFront と紐づけたドメイン>/index.html
にアクセスし、先ほど作成した index.html の内容が表示されれば OKです!
私の場合は、https://test.hisui-app.com/index.htmlにアクセスして確認します。
↓ のように表示されていれば OK です

アップロードした index.html はいらないので、消しておきます
// index.htmlを削除
app_to_S3$ aws s3 rm s3://hisui-react-app-bucket/index.html
delete: s3://hisui-react-app-bucket/index.html
// 削除されたか確認
app_to_S3$ aws s3 ls s3://hisui-react-app-bucket/
app_to_S3$
React アプリを作成する
作る場所は先ほどと同じ「app_to_S3」フォルダ内 React アプリを作成します。
// Reactアプリ作成
app_to_S3$ npx create-react-app react_to_s3
// ディレクトリを移動してアプリを起動
app_to_S3$ cd react_to_s3
react_to_s3$ npm start
// 起動すればOK!
// 確認出来たら終了する
React アプリをビルドして、S3 にアップロードする
// Reactアプリのビルド
react_to_s3$ npm run build
> react_to_s3@0.1.0 build
> react-scripts build
Creating an optimized production build...
One of your dependencies, babel-preset-react-app, is importing the
"@babel/plugin-proposal-private-property-in-object" package without
declaring it in its dependencies. This is currently working because
"@babel/plugin-proposal-private-property-in-object" is already in your
node_modules folder for unrelated reasons, but it may break at any time.
babel-preset-react-app is part of the create-react-app project, which
is not maintianed anymore. It is thus unlikely that this bug will
ever be fixed. Add "@babel/plugin-proposal-private-property-in-object" to
your devDependencies to work around this error. This will make this message
go away.
Compiled successfully.
File sizes after gzip:
46.62 kB build\static\js\main.430bb375.js
1.79 kB build\static\js\787.6268a133.chunk.js
541 B build\static\css\main.073c9b0a.css
The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.
The build folder is ready to be deployed.
You may serve it with a static server:
npm install -g serve
serve -s build
Find out more about deployment here:
https://cra.link/deployment
// buildフォルダへ移動
react_to_s3$ cd build
// ビルドで生成されたものをS3へアップロード
// aws s3 cp コマンドはワイルドカードで指定できないので、オプションを使う
// → https://blog.serverworks.co.jp/tech/2018/02/05/point-of-aws-cli-cp-to-s3/
build$ aws s3 cp ./ s3://hisui-react-app-bucket --recursive --exclude "" --include "*"
upload: ./asset-manifest.json to s3://hisui-react-app-bucket/asset-manifest.json
upload: ./favicon.ico to s3://hisui-react-app-bucket/favicon.ico
upload: ./robots.txt to s3://hisui-react-app-bucket/robots.txt
upload: ./index.html to s3://hisui-react-app-bucket/index.html
upload: static/css/main.073c9b0a.css.map to s3://hisui-react-app-bucket/static/css/main.073c9b0a.css.map
upload: static/js/787.6268a133.chunk.js to s3://hisui-react-app-bucket/static/js/787.6268a133.chunk.js
upload: ./manifest.json to s3://hisui-react-app-bucket/manifest.json
upload: static/css/main.073c9b0a.css to s3://hisui-react-app-bucket/static/css/main.073c9b0a.css
upload: ./logo192.png to s3://hisui-react-app-bucket/logo192.png
upload: static/js/main.430bb375.js.LICENSE.txt to s3://hisui-react-app-bucket/static/js/main.430bb375.js.LICENSE.txt
upload: static/media/logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg to s3://hisui-react-app-bucket/static/media/logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg
upload: ./logo512.png to s3://hisui-react-app-bucket/logo512.png
upload: static/js/main.430bb375.js to s3://hisui-react-app-bucket/static/js/main.430bb375.js
upload: static/js/787.6268a133.chunk.js.map to s3://hisui-react-app-bucket/static/js/787.6268a133.chunk.js.map
upload: static/js/main.430bb375.js.map to s3://hisui-react-app-bucket/static/js/main.430bb375.js.map
// アップロードされたか確認
build$ aws s3 ls s3://hisui-react-app-bucket/ --recursive
2023-06-14 23:24:52 605 asset-manifest.json
2023-06-14 23:24:52 3870 favicon.ico
2023-06-14 23:24:52 644 index.html
2023-06-14 23:24:52 5347 logo192.png
2023-06-14 23:24:52 9664 logo512.png
2023-06-14 23:24:52 492 manifest.json
2023-06-14 23:24:52 67 robots.txt
2023-06-14 23:24:52 1044 static/css/main.073c9b0a.css
2023-06-14 23:24:52 1535 static/css/main.073c9b0a.css.map
2023-06-14 23:24:52 4603 static/js/787.6268a133.chunk.js
2023-06-14 23:24:52 10592 static/js/787.6268a133.chunk.js.map
2023-06-14 23:24:52 144083 static/js/main.430bb375.js
2023-06-14 23:24:52 971 static/js/main.430bb375.js.LICENSE.txt
2023-06-14 23:24:52 373069 static/js/main.430bb375.js.map
2023-06-14 23:24:52 2632 static/media/logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg
WEB ブラウザからアクセスする
https://<CloudFront と紐づけたドメイン>/index.html
にアクセスし、今度は React アプリが表示されれば OKです!
私の場合は、https://test.hisui-app.com/index.htmlにアクセスして確認します。
↓ のように表示されていれば OK です

無事、構築完了しましたー!!、おわり。
構築にあたり遭遇したエラー集
参考
Discussion