【とりあえずハンズオン】EC2でReactを動かすだけの話

# はじめに

この記事では
EC2 上で React を動かすだけのハンズオン記事です。
ベストプラクティスや間違いがあれば
書き直していく予定です。

## 環境

- ヤマダにペペロンチーノをこぼされた初代 Surface Book

  - 実装 RAM 8GB

- エディション Windows 10 Pro
- バージョン 20H2
- OS ビルド 19042.867

- Chrome

  - 89.0.4389.90（Official Build） （64 ビット）

## ハンズオンセットアップ

ざっくり、流れを説明

1. AWS 上に EC2 を構築
2. Visual Studio Code で Remote SSH をインストール
3. Remote SSH の設定
4. EC2 に React をインストール
5. React を ローカルホストで実行

## AWS 上に EC2 を構築

まずはコンソールを開いて。。。
と以前から CloudFormation の記事で EC2 の構築をやっているので
今回は IaC で構築します。

### VPC を構築

まずは EC2 を置くためのサブネットを切る為に VPC を
CloudFormation で構築します。

CloudFormation の管理画面を開きます。
スタックの作成をクリック

![cfn_stack.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/c7a39a67-9e81-54a8-80ee-02d8cb2eaf52.jpeg)

```yml:vpc_network.yml

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  VpcCidrBlock:
    Description: VpcCidrBlock

    Type: String
    Default: 10.0.0.0/21

Resources:
  MainVpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidrBlock
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: MainVpcfromCF
  IGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: igw
          Value: igw-cf
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MainVpc
      InternetGatewayId: !Ref IGW

Outputs:
  MainVpc:
    Value: !Ref MainVpc
    Export:
      Name: MainVpcId
  MainIgw:
    Value: !Ref IGW
    Export:
      Name: MainIGWId
```

ファイル選択から vpc_network.yml をアップロードします。

スタック名は「vpc_network」とします。
![vpc_network-2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/5f590aa9-4fad-a548-e14c-33424c0559cd.jpeg)

### サブネットを切る

VPC が構築できたらサブネットを切ります。
今回は React アプリケーション公開用にセキュリティグループに TCP でポート 80 を開けます。

```yml:ReactSubnet.yml
AWSTemplateFormatVersion: 2010-09-09

Parameters:
  AZ:
    Description: AvailabilityZone
    Type: String
    Default: "ap-northeast-1a"
  PublicSubnetCidrBlock:
    Description: PublicSubnetCidrBlock
    Type: String
    Default: 10.0.2.0/24

Resources:
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AZ
      VpcId: !ImportValue MainVpcId
      CidrBlock: !Ref PublicSubnetCidrBlock
      Tags:
        - Key: Name
          Value: PublicSubnet
  PubRT:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !ImportValue MainVpcId
      Tags:
        - Key: PublicRoute
          Value: PublicRouteCf
  PubToInternet:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PubRT
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !ImportValue MainIGWId
  PubRTAssociate:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PubRT
  secSSHGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: PublicSecGrp
      GroupDescription: PublicSecGrp
      VpcId: !ImportValue MainVpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: PublicSecGrp

Outputs:
  PublicSubnet:
    Value: !Ref PublicSubnet
    Export:
      Name: PublicSubnet
  PublicSecGrp:
    Value: !GetAtt secSSHGroup.GroupId
    Export:
      Name: PublicSecGrp

```

ファイル選択から ReactSubnet.yml をアップロードしてスタックを作成
スタック名を「react-subnet」とします。

![react-subnet.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/3b92c222-a039-58a0-3c2b-23c478189b9a.jpeg)


スタックの作成には時間がかかりますので少し待ちましょう。

### キーペアを作成する

AWS コンソールから EC2 を開き、左ペインからキーペアを選択

![ec2_keypair.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/c70bd84a-59a0-6da1-4def-df0c6c1a9f92.jpeg)


キーペアを作成をクリック

![create_key_pair.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/af1b4de4-88a8-9264-900c-27245625230e.jpeg)

キーペアを「Mykeypair」という名前で作成

![Mykeypair.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/e7766f44-c416-1d7a-3017-c760b7c49fbc.jpeg)


### EC2 を構築する

CloudFormation の画面に戻り、EC2 を作成する。

```yml:public_react_ec2.yml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  myEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      KeyName: Mykeypair
      ImageId: ami-0992fc94ca0f1415a
      InstanceType: t2.micro
      Monitoring: false
      NetworkInterfaces:
        - AssociatePublicIpAddress: true
          DeviceIndex: "0"
          GroupSet:
            - !ImportValue PublicSecGrp
          PrivateIpAddress: "10.0.2.10"
          SubnetId: !ImportValue PublicSubnet
      Tags:
        - Key: Name
          Value: PublicEC2

```

ファイル選択から public_react_ec2.yml をアップロード

![cfn_public_react_ec2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/eea9c8b0-142a-543c-40df-b1aa7ee1da03.jpeg)

### スタックの完成予想図

![完成予想図.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/0db870d6-3c48-acec-0acd-44eb561d2094.jpeg)

### セキュリティグループの確認

SSH 用のポートと公開用のポート番号が開かれていることを確認しましょう。

![public_sec_grp.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/9662a8f2-3c20-4761-492c-08a883bb964b.jpeg)

## Visual Studio Code の設定

### Visual Studio Code で Remote SSH をインストール

EC2 に SSH でログインする為に
VisualStudioCode のプラグインである「Remote SSH」をインストールします。

まだ、インストールをしていない人は以下のようにインストールと表示されていると思います。

![remote_ssh.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/bdc62756-f530-7ecd-4e22-d9d1855a153b.jpeg)

インストールされている方は以下

![remote_ssh_OK.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/184e92b2-63ea-40cd-9cca-87a749ac2ea2.jpeg)

### Remote SSH の設定

Visual Studio Code の拡張機能 Remote SSH を設定します。

まず、Visual Studio Code の画面左下の緑ボタンを押します。

![green_button.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/2c0209eb-4fd3-8d77-dcb2-705f281da87e.jpeg)


するとウィンドウの上部に選択肢が出るので「Connect to Host...」を選択

![remote_ssh_select.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/c78ca4b1-d644-25d1-8dfa-afefa2873fa8.jpeg)


続いて「Configure SSH Hosts」を選択

![remote_ssh_select-2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/b2cd7e2e-7b4c-933b-a837-be13715295e6.jpeg)

Remote SSH の格納先を問われるのでユーザ名配下の.ssh を選択

![remote_ssh_select-3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/9b7386cd-b21d-0d97-2c08-e99a5ce8e791.jpeg)

以下の内容を環境に合わせて記載。

```txt

Host React-EC2
  HostName {パブリックIPアドレス}
  IdentityFile {キーペア名(フルパス)}
  User ec2-user

```

コンフィグを保存して閉じる。
再度、緑のボタンを押して Remote SSH 接続を開始すると新しいウィンドウが開かれる。
![react_remote_ssh_select-4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/89dccb02-1576-8b39-f9a1-fe725a0a7e88.jpeg)

### point

> The authenticity of host '54.178.82.82 (54.178.82.82)' can't be established.
> ECDSA key fingerprint is SHA256:sDZUv1irzZeafPa0UzdyNMmI0SGAViB5/ZTmRJ4vwG0.
> Are you sure you want to continue connecting (yes/no)?

SSH 接続する前にこんなことを聞かれたら yes と打って次へ

### React を試す

### EC2 React のセットアップ

「Open Folder 」を選択
![open_folder-1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/c59f7625-35ce-2321-102a-8311d94a3a5e.jpeg)


ディレクトリを選択
ec2-user のホームディレクトリ「/home/ec2-user/」を選択

![open_folder-2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/1beded3b-8b03-96f6-f75c-b9561d5678b6.jpeg)

Visual Studio Code のウィンドウ左ペインから
ファイルを新規作成

以下のような Bash スクリプトを書いて EC2 の「/home/ec2-user/」に保存する。

```bash:react-nginx.sh

# !/bin/bash
sudo yum update -y && \
sudo amazon-linux-extras install -y nginx1.12 && \
sudo systemctl start nginx.service && \
sudo systemctl enable nginx.service && \
sudo yum -y install git && \
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash && \
. ~/.nvm/nvm.sh
nvm install node && \
git clone https://github.com/ymd65536/react.git && \
cd react && \
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf_backup && \
sudo cp ./nginx.conf /etc/nginx/nginx.conf && \
sudo systemctl restart nginx && \
bash ./react_install.sh

```

react_install.sh は react リポジトリに格納

```bash:react_install.sh
# !/bin/bash
cd quick-react && \
npm install && \
npm run build && \
npm run start
echo "React Setup Complete!!"



```

&(アンパサンド)を使うことでコマンドの実行がこけた時の対策ができる。
例えば、今回のケースだと最初の yum がこけた場合は以降のコマンドは実行されない。
また、バックスラッシュでコマンド同士をつなぐとコマンド同士をつないでから実行するという意味になる。

作成した Bash スクリプトを実行する。

### HTTP で開く

http://localhost:3000/ を開く
※npm run start すると自動で開かれる。

![実行結果.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/4e353198-71af-9578-7031-697b334f9f74.jpeg)

ちなみに

https://twitter.com/ymd65536/status/1381918242394939392?s=19

## まとめ

今回は CloudFormation で VPC と EC2 を構築して React 環境を建てました。
次回はこの React をコンテナに入れたいと思います。

CloudFormation にスクリプトを埋め込めばもっと楽にできたなこれ。(あとの祭り)

## おわり