プライベートサブネットにEC2を置いたWebアプリケーションを作成する②

前章: [プライベートサブネットにEC2を置いたWebアプリケーションを作成する①](https://qiita.com/RHIC-0819/items/25bff36c3aacf92af28e)

## アプリケーションを立ち上げる

前回まででウェブアプリケーションの土台を作成したので、ようやく実際にアプリケーション構築に取り組みます。

本章は以下の手順で進めていきます
1. RDSを作成してEC2から接続する
1. EC2にアプリケーションを構築し、アプリケーションを立ち上げる
1. ALBを作成して、ローカルのブラウザから接続する

## 完成図
![alb-rds-ec2-完成図.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821799/d99f4a70-a09e-d1fc-b9df-91e9c347a87b.png)


## RDSの作成
マネジメントコンソールからRDSを開き、データベースの作成を選択します。

作成のポイントは4点です
1. **エンジンタイプの選択**
    今回はMySQLのバージョン8.0.35を利用していくため、エンジンタイプの設定は次のようになります。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821799/e9bdae9b-cdc0-86b2-f1fc-1d4f4ddb5e35.png)
    テンプレートは今回のような練習で作成する場合は無料利用枠で問題ありません。
    無料利用枠を選択すると自動的に単一のDBインスタンスとなり、余分なコストが発生するのを防ぐことができます。
1. **DBのユーザー名とパスワード**
    ここでは、データベース接続に使うマスターのユーザー情報を競ってします。
    セルフマネージドを選択しマスターユーザー名とパスワードを設定してください。
1. **EC2への接続**
    接続のセクションでは、「EC2コンピューティングリソースに接続」を選択することで、EC2からの接続が許可されるようにセキュリティグループに自動的に情報が追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821799/d376ae95-bac8-ed87-1fd6-ef3733c109cd.png)
1. **DBセキュリティグループの作成**
    RDS用のセキュリティグループを選択するセクションです。
    DBのセキュリティグループをEC2インスタンスと同じサブネット上に作成するように設定します。
    
その他の設定はすべてデフォルトのままで最下部まで行き、「データベースの作成」で終了です。

データベースが作成されたら、作成したDBの詳細画面からエンドポイントをコピーしておいてください。

## EC2インスタンスからRDSへの接続確認

前回の章で設定したセッションマネージャーからEC2にアクセスし、ec2-userでログインしなおします。

``` bash
$ sudo su --login ec2-user
```

:::note warn
セッションマネージャーではコピーやカットなどのショートカットは使えません。右クリックからコピーと貼り付けを選択してください。
:::

ログイン出来たらMySQLをEC2インスタンスにインストールします。
一つ目のコマンドはパッケージマネージャーのパッケージリストを最新のものにアップデートするもので、EC2インスタンスに初めてログインするときには、最初に行うことをお勧めします。

``` bash
$ sudo yum update -y
$ sudo yum -y localinstall  https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
$ sudo yum install mysql-community-client -y
$ sudo yum install mariadb105 -y
```

:::note warn
EC2インスタンスの作成に利用したAMIの設定によって上記のコマンドではインストールに失敗することがあります。ここで紹介しているのは、Amazon Linux 2023を選択した場合のやり方です。Amazon Linux 2を選択した場合はやり方が異なるので以下の他の方の記事等を参考にインストールを行ってください。

https://qiita.com/miriwo/items/eb09c065ee9bb7e8fe06
:::

では、接続していきます。

```bash
$ mysql -h {endpoint} -u {username} -p {password}
```

{ } の中身にはそれぞれ自分で作成したデータベースへのエンドポイント、マスターユーザー名、パスワードを代入してください。


```bash
mysql>
```
のように表示されていれば接続成功です。
使用する予定のデータベースを作成しておきましょう。

```sql
CREATE DATABASE flash_card;
```

接続が確認できたら`Ctrl + C`もしくは`exit;`でログアウトしておいてください。


## アプリケーションの立ち上げ

RDSで接続出来たら、ようやく簡単なアプリケーションを立ち上げていきましょう。
個人的に、Java Springを利用することが多いので、Java Springを利用したアプリケーションを使っていきます。

### Gitのインストール

以下のコマンドでGitをインストールします。
```bash
sudo yum install -y git
```

### ソースコードのクローン

私が作成した簡単な単語帳アプリケーションをEC2にクローンしてみます。
リポジトリはこちらです。

https://github.com/RHIC-7/flash_card

```bash
$ git clone https://github.com/RHIC-7/flash_card.git
```

クローンしたら、 `src/main/resources/application.yaml` にある、url, username, passwordの値を自分のRDS情報に書き換えてください。urlは`localhost`の部分をエンドポイントに修正します。
```yaml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/flash_card 
    username: ${SQL_USER}
    password: ${SQL_PASS}
```

### JAVAのインストール
amazon correttoというamazonが

```bash
sudo yum install java-17-amazon-corretto-devel
```


### アプリケーションの起動

ここまで修正したら、Springを起動します

``` bash
$ cd flash_card
$ chmod +x gradlew
$ ./gradlew build
$ nohup ./gradlew bootRun > spring.log 1<2&
```

このnohupコマンドを利用することでセッションマネージャーの接続を切ったとしてもアプリケーションは動き続けます。この時の標準出力は全て`spring.log`というファイルにリダイレクトされているので、catコマンド等で進捗を確認できます。


## ALBの作成

プライベートサブネットに置いたWebサーバをインターネットからアクセスするために、パブリックサブネットに踏み台としてのALBを設置します。

マネジメントコンソールからEC2に移動し、左のメニューバーから「ロードバランサー」→「ロードバランサーを作成」→「Application Load Balancer」を作成選択して作成していきます。

![スクリーンショット 2024-07-15 152547.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821799/6791196a-dbe5-3687-aafb-0d51c6c86d9f.png)

### 基本的な設定
このセクションは名前を入力したらデフォルト設定のままで問題ありません。

### ネットワークマッピング
設置するVPC、AZを選択し、その中のパブリックサブネットを選んでください。ここでは、AZを2つ選択する必要がありますが、最初のVPCの作成時にデフォルトで2つのAZにまたがって作成しているので、そちらを選択してください。

### セキュリティグループ
ALB用のセキュリティグループを作成していない場合は、「新しいセキュリティグループを作成」をクリックして、作成します。
インバウンドには、カスタムTCPでポート番号`8080`に対して、全てのIPアドレス範囲からのアクセスを許可するように設定してください。（Spring bootがデフォルトで8080番ポートを利用するため）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821799/955c909a-7e84-74c6-008b-1349a0ca7630.png)

:::note warn
セキュリティ上の懸念がある場合には、特定のIPアドレスからのみアクセスを受け付けるように、ソースを設定してください。
:::

### リスナーとルーティング
ここではまず、「ターゲットグループの作成」をクリックしてターゲットグループを作成します。すると、ターゲットグループの作成画面に遷移するので名前を入力します。
続いて、プロトコルをHTTPのポート番号8080に変更し、使用するVPCを選び、それ以外の箇所はデフォルトのままで次へを押します。


ヘルスチェックの詳細設定を開き、成功コードを200から302に変更してください。
これは、作成したjavaアプリケーションがルートへのアクセスをsign-in画面にリダイレクトさせているためです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821799/37615ff2-7a52-b063-627e-6b72a8d4951c.png)

VPCを適切に設定していれば、次の画面で作成したEC2インスタンスが現れます。画面中央のポート番号を8080に修正したら保留中として以下を含めるをクリックし、インスタンスの情報が下に移動するのを確認します。

そしたら、「ターゲットグループの作成」を押して完成です。

作成されたら、ALBの作成画面に戻り、リロードボタンを押すと先ほど作成したターゲットグループが選択できるようになっているので、そちらを選択してください。

---

そのほかの設定はすべてデフォルトのままで最下部まで行き、作成します。
作成されたら、ALBのDNS名をコピーしておきましょう。

このALBのセキュリティグループからのアクセスを許可するようにEC2インスタンスのセキュリティグループを編集します。ALBからはHTTPの8080番ポートへのアクセスのみを許可するので、ソースではALBに適用しているセキュリティグループを選択してください。今回は、外部からのEC2へのアクセスを全てブロックしたいので、IPアドレスで直接指定することはしないでください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821799/ec300abe-22c0-093d-9ab4-7a98a0ea3e27.png)



## 接続の確認

全セクションで作成したターゲットグループのヘルスチェックを確認し、正常になっていればアプリケーションも正常に立ち上がっており、アクセス可能になっています。

もしここで、異常になっている場合は、アプリケーションの立ち上げもしくはセキュリティグループ等にエラーが発生しているはずです。確認してみてください。

ここまで確認したらブラウザから`http://{albのDNS名}:8080/`でアクセスしてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821799/f6f0f437-4e8b-c8c1-b9a6-a20ab5efbdde.png)


上の画面が出たら本章はクリアです！

接続が確認できない場合は、セキュリティグループ、application.yamlの設定などを確認してみてください。



---
**記事一覧**
[プライベートサブネットにEC2を置いたWebアプリケーションを作成する ーイントロー](https://qiita.com/RHIC-0819/items/76f14f82c6d6c7aadb68)
[プライベートサブネットにEC2を置いたWebアプリケーションを作成する①](https://qiita.com/RHIC-0819/items/25bff36c3aacf92af28e)
[プライベートサブネットにEC2を置いたWebアプリケーションを作成する②](https://qiita.com/RHIC-0819/items/f3755e02e16694792c4e)
[プライベートサブネットにEC2を置いたWebアプリケーションを作成する③](https://qiita.com/RHIC-0819/items/ab4883b6fa958b3d908b) <-- 次はこちら