🐍

【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 のプロジェクトを作成できる

構築のざっくりとした流れ

  1. Terraform で AWS 環境を構築する
  2. React アプリを作成する
  3. 2. で作成したアプリを S3 にデプロイする
  4. WEB ブラウザからアクセスする

やってみる

Terraform で AWS 環境を構築する

ソースコード

https://github.com/hisuihisui/terraform_aws_deploy_practice/tree/react_aws_deploy/react_deploy

詳細はリポジトリ内の 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 の中身は以下。

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 です

無事、構築完了しましたー!!、おわり。

構築にあたり遭遇したエラー集

https://zenn.dev/kuuki/articles/error-aws-terraform-cloudfront-acm-cant-access/

https://zenn.dev/kuuki/articles/error-cloudfront-access-log-s3-enable-acl/

https://zenn.dev/kuuki/articles/error-aws-terraform-acm-dns-auth/

参考

https://registry.terraform.io/providers/hashicorp/aws/latest/docs

https://qiita.com/NorihitoYamamoto/items/63df7d87dfd67628d775

https://zenn.dev/jinwatanabe/articles/df80755b5e5b8b7052f7

https://zenn.dev/kou_pg_0131/articles/tf-cloudfront-oac

Discussion