[ハンズオン] AWS上でVue.js+SpringBootのアプリを動かす

# 目的　背景
私事ながら転職をすることになり、今まではアプリ側の経験しかありませんでしたが、転職先の会社ではAWSを経験できる環境があるとのことで事前準備としてAWSの学習を行なっています。実際に幾つかのハンズオンを経験する中で、指示に従って設定するだけで自分の頭を使って試行錯誤する感覚が薄かったので、実際に自分で作成したアプリをデプロイすることでいろんな罠に引っかかりながら理解を深めようと思い、それが誰かの役に立てば嬉しいなと思い執筆しました。AWS初学者なので、間違っていることもあるかもしれませんので、その際はご指摘よろしくお願いします🙇

# 目次
1. 構築するインフラ構成
2. 事前準備
3. ネットワーク構築
4. S3構築
5. DB構築
6. EC2構築
7. アプリの動作確認
8. 補足　セキュリティグループの設定
9. 最後に
10. 参考資料  

# 構築するインフラ構成

![スクリーンショット 2025-02-15 12.10.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/2d3f9643-f66b-4377-bf5e-acfa5df56085.png)

今回は上のような構成を構築します。
VPCを作成して、その中にパブリックサブネットとプライベートサブネットを2つずつ配置します。プライベートサブネットには、APサーバを2つとDBサーバを1つ構築します。またこれらのプライベートサブネットにアクセスするためのリソースとして、踏み台サーバをパブリックサブネットに構築します。コマンド実行やデプロイ作業はすべてこの踏み台サーバを経由することにより、APサーバやDBサーバーを安全なプライベートサブネットに配置しながら作業を進めることができます。
また、S3にVueのアプリをデプロイして、APサーバへのアクセスの際にALBを経由させて負荷分散を実施します。



# 事前準備
## 前提条件
### Vue.js
- Node.js 16.x以上
- npm 8.6.0
### SpringBoot
- Java17

事前にこれらの環境を構築した上で、以下のサンプルコードを私のGitHubから持ってきてください。
こちらのサンプルアプリをAWS上で動かしてみたいと思います。

https://github.com/Kyle-1106/practiceForAWS/tree/master






# 3.ネットワーク構築


まずはVPCを構築します。
![スクリーンショット 2025-02-05 21.18.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/1a33c9bc-d61b-b91b-9071-a48ed9d7bbf6.png)

今回はCIDRを192.168.0.0/16にしました。
CIDRを設計する際に気を付けるポイントは以下になります。

### CIDRは/16~/24にする
CIDRは/16から/24の範囲で設定することが一般的です。これはIPアドレスを枯渇させないためです。
VPCのCIDRの設計はサブネットの数を考慮する必要があります。
/16ということはそのVPCの中に2^16=65536個のIPアドレスが存在することになり、
/24ということはそのVPCの中に2^8=256個のIPアドレスが存在することになります。
私はインフラ構築を実務で経験したことがないのでそんなに必要なのかとは思いますが、必要なのでしょう🧐


### プライベートIPアドレスを割り当てる
プライベートIPアドレスとは以下のようなIPアドレスです。


| クラス | NWアドレス |
|:-:|:-:|
| A  | 10.0.0.0~10.255.255.255  |
| B  | 172.16.0.0~172.31.255.255  |
| C  |192.168.0.0~192.168.255.255|

これらの中から選びましょう。


### IPアドレスの重複に気をつける
オンプレミスとのハイブッド環境などでは、オンプレミスのIPアドレスと重複しないように注意しましょう。

## サブネットの設計
次に作成したVPCにサブネットを作成します。

![スクリーンショット 2025-02-05 21.38.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/40fc8557-bcc7-e25d-62d6-483e713fabea.png)



今回はVPC(192.168.0.0/16)の中に、192.168.1.0/24~192.168.4.0/24の4つのサブネットを作成します。

![スクリーンショット 2025-02-06 20.36.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/4a0673da-c5f4-b5c1-0a1d-a7b2cb069d6d.png)

| 名前 | サブネット |
|:-:|:-:|
| private-1a  | 192.168.1.0/24  |
| private-1c  | 192.168.2.0/24  |
| public-1a   | 192.168.3.0/24  |
| public-1c   | 192.168.4.0/24  |

サブネットの設計について意識するポイントは以下になります。

### /24などの大きめのサブネットを作成する
VPCと同じ理由でIPアドレスが枯渇しないようにするためです。

### 予約済みのIPアドレスに注意する
各サブネットのCIDRブロック内で、以下の5つのIPアドレスは予約されており、使用できません。

- ネットワークアドレス（例: 192.168.1.0/24 の場合、192.168.1.0）
- VPCルーター用（例: 192.168.1.1）
- Amazon提供のDNSサーバー（例: 192.168.1.2）
- 将来の利用のために予約（例: 192.168.1.3）
- ブロードキャストアドレス（例: 192.168.1.255）

詳細については、AWS公式ドキュメントをご参照ください。

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/subnet-sizing.html?utm_source=chatgpt.com



## インターネットゲートウェイの設定
次にインターネットゲートウェイを設定します。
インターネットゲートウェイは、VPC内のリソースがインターネットと通信するための出入口となる重要なコンポーネントです。
これを設定しないとVPC内のインスタンスはインターネットに接続できません。
以下のように名前のみ指定して作成します。
![スクリーンショット 2025-02-05 21.49.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/1b9cc16c-06db-593a-14c4-d146e0388ae6.png)

またインターネットゲートウェイは作成しただけでは、VPCとインターネットを接続しません。作成したインターネットゲートウェイをVPCにアタッチする必要があります。
![スクリーンショット 2025-02-05 21.51.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/b7dba7ba-8bf6-c953-e35a-97ad0b0e8b6c.png)

## ルートテーブルの設定
次にルートテーブルを設計します。ルートテーブルは、VPC内および外部へのトラフィックの経路を定義します。各サブネットに関連付けることで、サブネット内のリソースがどのように通信するかを制御できます。
privateサブネットとpublicサブネット両方にそれぞれ作成します。

![スクリーンショット 2025-02-05 21.55.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/18a53d1a-9472-15a9-d854-5e6c9c9af526.png)

![スクリーンショット 2025-02-05 21.55.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/ad9e9c28-77e4-4364-b289-05cbfa7680e0.png)

### ルートテーブルとサブネットの関連付け
次にルートテーブルとサブネットの関連付けをします。
パブリックサブネット
![スクリーンショット 2025-02-06 21.35.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/fa05828f-e38d-e786-00ef-c815ea0f5410.png)
プライベートサブネット
![スクリーンショット 2025-02-06 21.35.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/af27f241-d9bc-db5a-5ab6-5603563ac7ce.png)
こうすることでプライベートサブネットとプライベートルートテーブル、パブリックサブネットとパブリックルートテーブルが関連づけられました。



### ルートテーブルにインターネットゲートウェイを登録
最後にパブリックルートテーブルに対して、インターネットゲートウェイを登録します。この作業を行うことで、パブリックサブネットは初めてインターネットからアクセスできるようになります。


![スクリーンショット 2025-02-07 6.46.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/1e1abc47-1ce0-2cd6-12cf-ffe7d18d1f63.png)



ここまででルートテーブルの設定も完了しました。


# 踏み台サーバ構築
次にプライベートサブネットに存在するEC2にアクセスするための踏み台サーバを構築します。まず一般的にAPサーバ(EC2)はセキュリティの観点からプライベートサブネットに配置します。ただ、これだとインターネット経由でアクセスができないため、運用時に不便なため、踏み台サーバを構築し、踏み台サーバからAPサーバに通信することでセキュリティを担保しながら作業を進めることが可能になります。

### セキュリティグループ作成
踏み台サーバ用のセキュリティグループを作成します。
先に踏み台サーバにどのような通信が発生するのかを確認します。
![スクリーンショット 2025-02-15 12.25.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/abc352d0-8d07-4e4d-b9c9-3adc8c385125.png)
少しわかりにくいですが、整理すると以下になります。

| イン/アウト | 通信相手 |
|:-:|:-:|
| インバウンド  | 運用PCからのSSH通信  |
| アウトバウンド  | APサーバ1  |
| アウトバウンド  | APサーバ2  |
| アウトバウンド  | DBサーバ  |


踏み台サーバには、ローカルのPCからSSH接続を行うので、インバウンドルールにSSHを設定します。本来は接続元も自分のIPアドレスを指定した方がよりセキュリティは高まりますが、今回は指定しません。アウトバウンドに関しては、まだこの時点でAPサーバ用、DBサーバ用のセキュリティグループを作成していないのでまだ指定しなくて構いません。


![スクリーンショット 2025-02-06 21.19.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/46c14c1b-f3fc-6a9e-9902-a611eea3f5cb.png)


### 踏み台サーバ構築
次に踏み台サーバの実態となるEC2を建てます。デフォルト設定から変更する箇所だけ画像を貼ります。
キーペアを作成します。
![スクリーンショット 2025-02-06 21.03.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/15820fae-9e97-9f4d-d098-b2c8f3c6d032.png)
キーペアを作成ボタンをクリックすると勝手にダウンロードされるので、保管しておいてください。これはEC2にアクセスする際に必ず必要な秘密鍵になりますので紛失しないように注意してください。


VPCは自分の作成したVPCを選択して、踏み台サーバはパブリックサブネットに配置するので、public-1aを選択します。SSH接続をする際にIPアドレスを指定しないといけないのでパブリックIPを自動割り当てを有効化します。セキュリティグループは先ほど作成したものを選択します。
ここまでできたらEC2を起動してください。


![スクリーンショット 2025-02-06 21.20.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/e46255f7-5cb0-bb1c-7614-7eb3e19a2bae.png)

### 踏み台サーバ接続
踏み台サーバが起動できたら、踏み台サーバに接続できることを確認してみましょう。以下のコマンドを実行してください。
```bash
chmod 400 秘密鍵
```
```bash
ssh -i 秘密鍵 ec2-user@踏み台サーバのパブリックIP
```
![ec2-user_ip-192-168-3-160__-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/0fc737f8-a8be-2760-84da-f8260a220bac.png)

上の画像のようになればEC2に対してログイン成功です！
もしうまくいかない場合は以下の観点で確認してみてください。
<details><summary>うまくいかない場合</summary>

- 踏み台サーバ用のセキュリティグループのインバウンドルールにおいて、インターネット上（0.0.0.0/0）からのSSH通信を許可しているか
- パブリックサブネットにルートテーブルが紐づいているか
- パブリックルートテーブルにインターネットゲートウェイが紐づいているか
- EC2インスタンスが起動しているか
- キーペアが正しいか 

</details>

ここまでできたら踏み台サーバの構築が完了しました。

# DBの構築
まずは、DBを構築します。初めにDB用のセキュリティグループを作成します。

## セキュリティグループの作成
踏み台サーバの時と同様再度、通信を確認します。

![スクリーンショット 2025-02-15 12.25.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/2d062259-098a-4f82-bcd3-9e362d33990a.png)

整理すると、

 イン/アウト | 通信相手 |
|:-:|:-:|
| インバウンド  | 踏み台サーバ  |
| インバウンド  | APサーバ1  |
| インバウンド  | APサーバ2  |


DBはプライベートサブネットに存在しており、インターネット上から直接アクセスすることができないので、踏み台サーバを経由してアクセスします。また、APサーバからもアクセスします。この時点では踏み台サーバのセキュリティグループしか作成していないので一旦、踏み台サーバのセキュリティグループを設定します。タイプはPostgreSQLを指定します。
![スクリーンショット 2025-02-07 7.21.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/0622d9ce-5b6e-0379-d7be-41a2a48d5d4a.png)

## PostgreSQL構築
次にDBサーバを構築します。設定箇所が多いため、デフォルト設定から変更した箇所のみ記載します。
エンジンはPostgreSQLを選択して、テンプレートは無料利用枠を選択します。

![スクリーンショット_2025-02-09_9_26_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/15d16291-4ff3-0b67-bc65-13e9e8072957.png)


マスタユーザ名とパスワードはご自身のお好きなように設定してください。
![スクリーンショット_2025-02-07_7_31_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/2d9e11c2-d4ae-36b1-ed61-a373180dfe72.png)

VPCは自分の作成したものを選択して、セキュリティグループはDB用のセキュリティグループを選択してください。
![スクリーンショット_2025-02-07_7_31_23-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/eb66065e-6a57-1eac-ab44-1998b24d33b6.png)

追加設定でDBサーバの名前を設定してください。

![スクリーンショット_2025-02-07_7_31_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/95f9045a-28df-f4db-d022-63468af67f8f.png)


## 踏み台サーバからDBにアクセスしてみる
### セキュリティグループの編集
踏み台サーバからPostgreSQLに接続し、操作するためには踏み台サーバに対してpsqlをインストールする必要があります。ただ今のままでは、踏み台サーバはインターネットからpsqlをインストールすることができないのでセキュリティグループに新たに以下の設定を追加します。また、先ほどDBのセキュリティグループを作成していないため保留にしていた、DBセキュリティグループへのアウトバウンド設定も追加します。

踏み台サーバに対して
すでに設定している内容↓
| イン/アウト | 通信相手 |
|:-:|:-:|
| インバウンド  | 運用PCからのSSH通信  |
| アウトバウンド  | APサーバ1  |
| アウトバウンド  | APサーバ2  |
| アウトバウンド  | DBサーバ  |


踏み台サーバに対して
追加設定する内容↓
| イン/アウト | 通信相手 |
|:-:|:-:|
| アウトバウンド  | インターネット(HTTP)  |
| アウトバウンド  | インターネット(HTTPS)  |
| アウトバウンド  | DB用セキュリティグループ  |

※踏み台サーバからAPサーバにSSH通信するのでその設定が抜けていますが、まだAPサーバ用のセキュリティグループを作成していないので後ほど設定します。


![スクリーンショット 2025-02-07 16.45.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/c5bda430-8432-0c72-8665-8f6ff6e05d80.png)

ここまでできたら踏み台サーバにログインして、次のコマンドを打ち込んでください。

```bash
sudo yum update -y
```


次にCloudShellを起動して、PostgreSQLのバージョンを確認します。
CloudShellって何？という方は以下の記事を参考にして起動してみてください。

https://qiita.com/miyuki_samitani/items/c7ad49d6264568b578c9


CloudShellを起動して次のコマンドを打ってください。
```bash
aws rds describe-db-engine-versions --default-only --engine postgres
```
![スクリーンショット 2025-02-09 9.31.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/bc300989-908e-7e86-0fbe-df9fc5879e47.png)

このコマンドを実行することでPostgreSQLのバージョンを確認します。私の環境ではバージョン16でした。

ここまでできたら、いよいよ踏み台サーバにpsqlをインストールします。ご自身の環境のDBバージョンに合わせてください。踏み台サーバにログインして以下のコマンドを打っていってください。

```bash
sudo yum install -y postgresql16
```
インストールが完了したら念の為インストールできたかを確認してください。
```bash
psql --version
```
バージョンが表示されればOKです。やっとここまででDBに接続する準備ができました。

ここまでできれば、以下のコマンドで実際にDBに接続してみてください。
```bash
psql -h <RDSのエンドポイント> -U <ユーザー名> -d <データベース名>
```

ちなみにRDSのエンドポイントは以下に記載があります。
![スクリーンショット_2025-02-07_16_53_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/ea0c7ade-a40d-7f37-d718-3f035417d4be.png)
ユーザ名とデータベース名は私と同じ設定であれば以下になります。
| 項目 | 設定値 |
|:-:|:-:|
| ユーザ名  | postgres  |
| データベース名  | postgres_server  |


下のようになれば接続できています！

![スクリーンショット_2025-02-07_16_50_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/3f927a5b-3193-56b2-551e-910e6dc92854.png)


## テーブル作成&サンプルデータ投入
次にテーブル作成とサンプルデータの投入をします。
サンプルアプリの以下のディレクトリのschema.sqlにまとまっています。
![スクリーンショット 2025-02-08 10.03.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/1d20aff7-f567-85e0-3039-434c41d3b49e.png)


###  schema.sqlを踏み台サーバにコピー
DBサーバへの操作は踏み台サーバからしかできないので、踏み台サーバにschema.sqlを送信し、踏み台サーバでsqlを実行してDBにテーブル作成&データを追加します。

以下のコマンドをローカルで実行して下さい。
ローカルのschema.sqlを踏み台サーバに転送します。
```bash
scp -i [秘密鍵.pem] ローカルのschema.sqlのパス 踏み台サーバの保存先パス
```
![スクリーンショット_2025-02-08_9_17_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/5f422311-c464-0d3d-76f8-c62a02ec6706.png)

次にちゃんと踏み台サーバにデータが転送されてるかを確認します。
踏み台サーバにログインして、ご自身が転送されたパスにschema.sqlがあれば成功です。
![スクリーンショット_2025-02-08_9_21_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/cae2fa56-83e7-41b0-5a4b-af4052b0e633.png)


### SQLを実行してDBにデータを追加
次に踏み台サーバにログインして、schema.sqlを実行してDBにデータを追加します。以下のコマンドを実行してください。

```bash
psql -h <エンドポイント> -p <ポート番号> -U <ユーザー名> -d <データベース名> -f schema.sql
```
![スクリーンショット_2025-02-08_9_29_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/371ad09b-200c-16ee-e392-e72e1a4d3764.png)
上のようになれば成功しています。念の為、本当にデータがあるかを確認しています。

![スクリーンショット_2025-02-08_9_34_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/5479ecf9-ff7e-0d43-a531-eb28044755e4.png)

ここまででDBの構築とセットアップが完了しました。









# APサーバ構築
次にAPサーバを構築していきます。

## EC2用セキュリティグループの作成
APサーバを構築する前に、APサーバ用のセキュリティグループを作成します。


![スクリーンショット 2025-02-15 12.25.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/2d062259-098a-4f82-bcd3-9e362d33990a.png)

| イン/アウト | 通信相手 |
|:-:|:-:|
| インバウンド  | 踏み台サーバ用セキュリティグループ |
| アウトバウンド  | インターネット(HTTP)  |
| アウトバウンド  | インターネット(HTTPS)  |
| アウトバウンド  | DB用セキュリティグループ  |

APサーバへのアクセスは踏み台サーバ経由で行うため、インバウンドで踏み台サーバ用のセキュリティグループを指定します。またELBを経由して負荷分散を行うため、本来はインバウンドとして、ELB用のセキュリティグループも設定が必要ですが、これはまだ作成していないので保留します。アウトバウンドではDBサーバにアクセスするため、DB用セキュリティグループを指定します。また、Javaのインストールなどをインターネット経由で行うため、HTTP,HTTPSを指定します。


![スクリーンショット_2025-02-08_9_41_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/7a67b02b-2094-4441-d017-7cf9ad8b1b4f.png)

### 踏み台サーバセキュリティグループ編集
踏み台サーバのセキュリティグループのアウトバウンドルールでAPサーバのセキュリティグループを指定しないといけませんでしたが、まだ未作成で設定できていなかったのでこのタイミングでしておきます。

![スクリーンショット_2025-02-08_17_39_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/0b19c065-b220-3062-1ba6-a8f1dc56f230.png)


## NATゲートウェイの構築
APサーバはプライベートサブネットに存在しています。これからEC2の構築をするにあたって、APサーバにJavaをインストールする必要があります。ただ、今のままではインターネットに接続することができないのでNATゲートウェイを構築します。NATゲートウェイはインターネットからAPサーバに接続することはできませんが、APサーバからインターネットの単方向のみ接続できるというものです。
### NATゲートウェイ作成
VPCのサイドバーよりNATゲートウェイを選択して、以下のような設定にします。
サブネットはパブリックを選択して、ElasticIPの割り当てを選択します。
![スクリーンショット 2025-02-09 9.01.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/853a738a-1a59-3307-17e0-b4bc45ae29d9.png)

### ルートテーブルの編集
プライベートサブネットのルートテーブルを選択します。
送信先を0.0.0.0/0(インターネット)を指定してターゲットで先ほど作成したNATゲートウェイを選択します。これでNATゲートウェイが使えるようになりました。

![スクリーンショット 2025-02-09 9.02.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/5f7411ad-0e10-98ca-8f4d-096bbb2a5aab.png)



## APサーバの構築
APサーバ用のEC2を2台立てていきます。

APサーバは2つ構築するので、ap-server-1,ap-server-2としてください。
![スクリーンショット 2025-02-08 9.54.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/1b85eb38-8ac8-3ccf-dd33-4d2efb124e31.png)
![スクリーンショット 2025-02-08 9.57.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/c7854059-5202-fbfd-f1ae-93b61c6fc2dc.png)

NW設定に関してはサブネットだけ異なるので注意してください。どちらもprivateを選択してください。

![スクリーンショット_2025-02-08_9_54_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/7e674ff3-176b-de84-ed46-2ae388821a89.png)
![スクリーンショット_2025-02-08_9_57_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/d0beb50a-8fce-eb1c-2dc3-e2faf056061a.png)

ここまでできたらEC2を起動してください。


## ELBの設定
次にリクエストを二つのAPサーバに分散させるためにELBを作成します。

### セキュリティグループを作成
インバウンドルールはインターネットからのアクセスを許可するのでHTTP,HTTPSを許可します。
アウトバウンドルールはAPサーバに振り分けるのでポートは8000(Springbootアプリがポート8000で起動する)でセキュリティグループはAPサーバ用を指定します。
![スクリーンショット 2025-02-08 10.19.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/a907e766-199f-1d4d-573f-21c42f823aa5.png)

### ターゲットグループの作成
ターゲットグループとはロードバランサーの負荷分散先のことです。

![スクリーンショット_2025-02-08_10_42_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/31486ba4-9dbb-4c8e-63ad-302336b8f83e.png)

![スクリーンショット 2025-02-08 10.42.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/248c4911-8643-67c7-47a2-cdfbbd90f962.png)

### ELBの作成
今回はインターネットからのアクセスをEC2に分散するのでALBを選択します。基本はデフォルトの設定で構いません。アベイラビリティゾーンはこのALBが動作するAZを選択するため、public-1aとpublic-1cを選択します。セキュリティグループは先ほど作成したELB用を選択します。ターゲットグループも先ほど作成したものを選択します。

![スクリーンショット 2025-02-08 10.45.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/b0188d95-7d7c-7b07-3807-c40f495bedc4.png)

### APサーバ用セキュリティグループの編集
先ほどAPサーバ用のセキュリティグループを作成しましたが、まだELBを未作成だったため、ELBのセキュリティグループからのインバウンドルールの設定を保留にしていました。ここで、APサーバ用セキュリティグループに対して、ELBからのインバウンドルールを設定します。

![スクリーンショット_2025-02-15_15_54_42-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/599de096-327c-49c7-883f-9b78dec2ff0e.png)

ここまできたら、いよいよEC2にSpringbootアプリをデプロイしたいのですが、CORSの関係上、通信を許可するドメインを指定した上でアプリをビルド&デプロイする必要があります。ドメインについてはS3の設定を先に行わないとわからないため、中途半端ですが先にS3の設定を行います。



# S3構築
S3を構築して、VueアプリをS3にデプロイします。

## Vueアプリの準備
まずはデプロイするVueアプリの準備をします。

### パッケージインストール
clientディレクトリに移動して、以下のコマンドを実行してパッケージをインストールしてください。
```bash
npm install
```
### 環境変数の設定
ご自身の環境に応じて環境変数を設定します。このアプリでは.env.productionでAWSにデプロイする用の環境変数の設定を行います。該当ファイルは以下のディレクトリに存在します。

![スクリーンショット 2025-02-12 19.09.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/3236949d-dd9f-4e2d-83df-94a2832cd05d.png)

上記の.env.productionにロードバランサーのDNS名を指定してください。
![スクリーンショット_2025-02-12_19_08_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/54ce9285-36ec-4124-8a5a-400b860388c8.png)
ちなみにロードバランサーのDNS名は以下にあります。
![スクリーンショット_2025-02-12_19_12_56-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/5a9f84fe-1d71-4a5d-a253-211d60d71fc3.png)

これはソースを見てもらえればわかるのですが、APIエンドポイントを指定しています。今回はAPサーバに直接リクエストを送信するのではなくて、ALBを経由するため、ここでALBのDNS名を指定する必要があります。

![スクリーンショット_2025-02-15_16_00_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/19daf59a-9463-4320-b817-790f2de71fb0.png)


次に以下のコマンドを実行してビルドしてください。
```bash
npm run build
```
これでdistフォルダ配下にファイルが生成されればOKです。
![スクリーンショット 2025-02-15 9.46.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/efc2b788-05a1-4373-8ee0-1f458d77390e.png)




## S3バケットの設定
### バケットの作成
まずはS3バケットを作成します。
![スクリーンショット_2025-02-12_19_20_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/de7f0a6e-20a0-4dd0-b2ad-350595ffc4f6.png)
注意点としてはバケット名はグローバルで一意でないといけないので、ご自身の好きなものに設定してください。またパブリックアクセスの設定についてはインターネットからアクセスしたいので、チェックを外してください。


### ビルドファイルのアップロード
ビルドファイルをアップロードします。
![スクリーンショット 2025-02-12 20.24.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/2219d447-2fcb-44d0-96b0-b08b17c8e063.png)
distフォルダ配下にあるファイルたちをS3にアップロードします。

![スクリーンショット 2025-02-12 20.26.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/bd8a615b-0b6e-4cad-a689-e80ffe5677f4.png)

次にバケットタグに移動して、一番下の静的Webサイトホスティングを有効にします。
![スクリーンショット_2025-02-12_20_39_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/bef4a59d-1c5e-463d-8f67-c9bb309cde55.png)

![スクリーンショット_2025-02-12_20_39_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/ada7fc15-6d56-40dd-a438-8c1793b1faf2.png)

インデックスドキュメントとエラードキュメントは両方index.htmlに設定します。
![スクリーンショット_2025-02-12_20_39_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/bc478ee1-24ab-4e47-ab87-221a5645d521.png)


![スクリーンショット_2025-02-12_20_42_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/93440b40-5af1-456a-9931-5b65bb4e1e8d.png)
そうするとサイトのURLが生成されるので試しにこのURLにアクセスしてみます。

![スクリーンショット_2025-02-12_20_44_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/1c0a3ce0-7cf9-42c2-8ae6-d0bd041099c6.png)
すると403エラー（閲覧禁止）が返ってきます。
これはまだ、S3パケットに対して閲覧権限がないためです。そこでこのバケットに対するアクセス権限を変更して行きます。

### バケットの権限変更
アクセス許可タブに移動してバケットポリシーの編集を行います。
![スクリーンショット_2025-02-12_20_47_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/c0af0355-2428-4cc4-ad5b-b95f099f1909.png)
そして以下のJSONをコピペしてください。

```json
{
    "Version": "2012-10-17",
    "Id": "Policy1739401990507",
    "Statement": [
        {
            "Sid": "Stmt1739401980782",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::practice-for-aws-vue-backet/*"
        }
    ]
}
```
軽く説明すると、誰(Principal)がどこ(Resource)にどんな操作権限(Action)を持っているかを定義しています。この設定では、すべてのユーザが、practice-for-aws-vue-backet/配下のリソースに対して、オブジェクト(index.htmlやcssなど)を取得する権限を持っています。なので、画像のアップロードなどはできません。


一つ注意点として、arnに関してはご自身のものに置き換えてください。
ちなみにarnはここに表示されています。
![スクリーンショット_2025-02-13_8_21_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/bbaef7fa-a8a5-4b26-88d5-9656c508cd50.png)

そして再度サイトのURLにアクセスするとアクセスできました！！
![スクリーンショット 2025-02-13 8.23.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/22cfd778-09c0-4db1-a4f4-cf944cc944b1.png)

ちなみにポリシージェネレータというツールがあり、これを使えば自分でポリシーの設定を行うことができますので興味のある方は使ってみてください。

https://awspolicygen.s3.amazonaws.com/policygen.html

使い方は以下のサイトを参考にしてみてください。

https://aws.amazon.com/jp/blogs/aws/aws-policy-generator/



# SpringBootアプリのデプロイ
ここまで準備ができたらいよいよSpringbootアプリをデプロイしていきます。

## Springアプリの設定修正

まずはSpringアプリの設定変更を行います。
![スクリーンショット 2025-02-08 15.41.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/c18322cb-fc2d-e6a7-4375-b7588d294684.png)

application.properties絡みについて軽く説明すると下のようになります。
| ファイル名 | 役割  |
|:-:|:-:|
| application.properties  |  共通設定 |
| application-development.properties  | 開発用（ローカル動作確認）  |
| application-production.properties  | 本番用（AWSデプロイ用)  |

今からは実際にAWSにデプロイするので、application-production.propertiesをご自身のDB、CORS設定に修正してください。RDSのエンドポイントとS3のドメイン名を指定してください。
![Cursor_と_application-production_properties_—_pracitceForAWS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/fad5449f-1204-4bdc-a2ce-0f7359e398c5.png)


## Springアプリのビルド

serverディレクトリまでカレントディレクトリを移動してビルドしてください。

```bash
./gradlew build
```
以下のようになれば成功です！

![スクリーンショット_2025-02-08_15_49_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/36b57301-84e5-3864-5c27-5bc234a1f11b.png)

ビルドが成功すると以下の場所にjarファイルが作成されますのでこれをデプロイしていきます。
![スクリーンショット 2025-02-08 15.50.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/83930607-0be7-01e0-1ae3-de3451e367e5.png)

### Springアプリのデプロイ
デプロイも踏み台サーバ経由でしかできませんので、まずはローカルから踏み台サーバに対して
- ビルドで生成されたjarファイル(server-0.0.1-SNAPSHOT.jar)
- 秘密鍵
を転送します。

ローカルで以下のコマンドを実行してください。
```bash
scp -i 秘密鍵 送信するファイル ec2-user@<踏み台サーバのIP>:/home/ec2-user
```
秘密鍵の転送
![スクリーンショット_2025-02-08_17_43_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/cdb4f4ee-ff56-3d2b-f892-aa25e2d2eaa9.png)


JARファイルの転送
![スクリーンショット_2025-02-08_17_43_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/59507f59-3fbe-a51c-e2da-5b7894d37104.png)


踏み台サーバにログインして転送を確認できればOKです。

次は踏み台サーバに転送した二つのファイルをAPサーバ1,APサーバ2にそれぞれ以下のコマンドで転送します。
```bash
scp -i 秘密鍵 server-0.0.1-SNAPSHOT.jar ec2-user@<プライベートEC2のプライベートIP>
```

![スクリーンショット_2025-02-08_17_43_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/1a04d418-3f46-2c03-30b2-5bfbf830a7d8.png)


これでAPサーバにJARファイルを転送することができました！

### Javaのインストール
まだこのままではAPサーバにはJavaがインストールされていないので、Springbootアプリを動かすことができません。そこで、APサーバにJavaのインストールを行います。APサーバにログインして以下のコマンドを打ってください。
```bash
sudo yum install -y java-17-amazon-corretto-devel
```

### SpringBootアプリの起動
ここまでできたらあとはアプリを起動するだけです。以下のコマンドを打ってください。
```bash
java -jar server-0.0.1-SNAPSHOT.jar --spring.profiles.active=production
```
以下のように Started ServerApplicationと表示されれば成功です！！
![スクリーンショット 2025-02-09 9.57.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/2487f9da-09b5-42cc-13a6-b231f11c2c3a.png)

ここまできたらもう一つのAPサーバにも同様の手順でJavaのインストールとアプリのデプロイ、起動を行ってみてください。



# 動作確認
ここまでできたら、AWSの設定は完了です。実際にアプリが動くかどうかを確認してみましょう。
まずはログインページにアクセスしてください。
会員登録できていないと思うので、新規会員登録ページに遷移します。
![Cursor_と_client-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/b8f730eb-d4ac-4468-87cf-d44ed7f3c23a.png)

会員登録画面に遷移したら好きなユーザで新規会員登録を行ってください。

![client.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/e0948252-a070-4419-aa57-28103033a6a8.png)

登録をクリックすると再度ログインページに遷移しますので、先ほど登録したユーザでログインしてください。
![スクリーンショット_2025-02-15_16_23_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/c219bff7-487e-4830-8d90-418e6ef613b8.png)

ログインできたら、ハンバーガーメニューの書籍検索から書籍検索画面に遷移してください。
ここで検索ボタンをクリックすれば、いろんな書籍情報が一覧できます。


![スクリーンショット 2025-02-15 16.54.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/7ad518a1-04d8-419c-87ed-7c42864a24a1.png)

:::note warn
今回のハンズオンではAWS上にアプリをデプロイすることが目的のため、サンプルアプリはCursorを使って爆速実装し、簡単な動作確認しかしていません。それゆえアプリのレイアウト崩れや、不具合などあるかもしれませんがご了承ください🙇
:::


# 補足　セキュリティグループの設定
私が今回のハンズオンをやっていく中で、うまくいかなかったポイントの多くはセキュリティグループの設定が足りていないなどの要因でした。そこで念の為、私のセキュリティグループの設定を最後に載せますので、もしうまくいかない方はこちらを参考にしてみてください。



### ロードバランサー
インバウンド
![スクリーンショット 2025-02-15 16.42.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/b069834a-85ae-443f-bc8c-fb205365382b.png)

アウトバウンド
![スクリーンショット_2025-02-15_16_42_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/9b505f70-eb8d-4964-a912-418c84d1de47.png)

### 踏み台サーバ
インバウンド
![スクリーンショット 2025-02-15 16.48.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/36b9c920-90ec-4fb3-a0e7-f0c68f2d594f.png)

アウトバウンド
![スクリーンショット_2025-02-15_16_48_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/42ea9ac1-8a4e-4b69-adfb-3b6e924abbfd.png)



### APサーバ
インバウンド
![スクリーンショット_2025-02-15_16_45_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/236e1e6f-2ee1-467c-aad2-88ff6285fc99.png)

アウトバウンド
![VPC___ap-northeast-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/13313efa-f6b5-4783-b878-56306dcc815d.png)


### DBサーバ
インバウンド
![スクリーンショット_2025-02-15_16_51_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/12bf0b11-e348-431a-8153-5958b3506e48.png)


アウトバウンド
![スクリーンショット 2025-02-15 16.51.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458671/8d41d637-3873-4cb3-84bc-e47ac10a9ca1.png)





# 最後に
実際に自分でインフラ構成を考えて自分で作ったアプリをデプロイすることで、特にセキュリティグループやELBの設定周りなどを中心にいろんなところに詰まりました。そしてそれを解決する中で知識が深まっていきました。転職後はよりAWSなどを実務で触る機会も多いと思いますので積極的にチャレンジにしていきたいと思います。






















# 参考記事

https://www.udemy.com/course/webapplication-on-aws/?couponCode=V2JPLETSLEARN

https://dev.classmethod.jp/articles/tips-describe-db-engine-versions-for-postgresql/

https://blog.serverworks.co.jp/2023/04/10/142451?utm_source=chatgpt.com

https://zenn.dev/takuh/articles/4446e12c607a6b

https://zenn.dev/oreo2990/articles/d6e7837c64e6fc

https://www.isoroot.jp/blog/6705/