0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWSのRDSに作成したMySQLとEC2にあるSpringBootアプリを紐づける

0
Posted at

はじめに

今回は、EC2で公開しているSpring BootのWebアプリに、Amazon RDS for MySQLを接続する手順をまとめます。

これまではH2を使ってデータベースを利用してSpring Bootアプリを作成することは多いようです。本番環境ではRDS MySQLを使用し、アプリとは別にデータを管理できる構成にしていくのが一般的なようなのでやり方を学ぶことにしました。

この記事では、以下の状態を前提としています。

  • ローカル環境で、H2を使ったSpring Bootアプリが動作している
  • EC2でSpring Bootアプリを公開している
  • EC2のOSはUbuntuを使用している
  • Nginxを経由してWebアプリにアクセスできる
  • systemdでSpring Bootの起動・停止を管理している

上記の構成を作成する手順はこちらの記事を参照してみてください。
Spring Bootで作成したWebアプリをAWS EC2で公開する手順(パート1)
Spring Bootで作成したWebアプリをAWS EC2で公開する手順(パート2)
Spring Bootで作成したWebアプリをAWS EC2で公開する手順(パート3)
Spring Bootで作成したWebアプリをAWS EC2で公開する手順(パート4)
EC2にデプロイしたSpringBoot WebアプリをNginxを使って独自ドメインへのアクセスに切りかえる

作業後は、ローカル開発ではH2、本番環境のEC2ではRDS MySQLを使い分けられるようにします。

私自身、データベースやAWSを学びながら進めたので、設定項目や接続方法でつまずくことがありました。この記事では、接続確認の方法も含めて順番に説明します。

1. 現在のH2版アプリがローカル環境で正常に動作することを確認

RDSの設定を始める前に、現在のアプリがH2を使用して正常に動作することを確認します。

先に確認しておくことで、RDSへの切り替え後にエラーが出た場合、もともとのアプリの問題なのか、接続先を変更したことによる問題なのかを切り分けやすくなります。

2. RDS for MySQLを作成

ここが個人的には難関でした。EC2のインスタンスを作成するのは割と直感的でしたが、データベースに関する知識がない私からすると「わけがわからないよ」、状態でしたが何とかなりましたので皆さんもやり遂げられると思います。

今回は 「現在EC2でSpring Bootを動かしており、本番DBとしてAmazon RDS for MySQLを追加する」 という前提で説明します。

最終的には


                    インターネット
                          │
                          ↓
                       Nginx
                          │
                          │ :8080
                          ↓
                    Spring Boot
                          │
                          │ :3306
                          ↓
                 ┌────────────────┐
                 │ Amazon RDS     │
                 │     MySQL      │
                 └────────────────┘

という構成になります。

なお、最終的には

EC2
 │
 │ TCP 3306
 │
 ↓
RDS

のみのアクセスを許可しRDSの3306番ポートを、0.0.0.0/0を避けます。

2-1. AWSコンソールからRDSを開く

AWSマネジメントコンソールにログインします。
サービス検索で、

RDS

を検索すると

Aurora and RDS

というのが表示されるのでこれをクリックします。
その後データベースの作成というボタンをクリックします。

いくつか作成方法が表示されるので、「フル設定」を選択します。

詳細な設定画面が出ますので、この後設定していきます。

2-2. エンジンをMySQLにする

エンジンのオプションという項目があるので、

MySQLを選択します。

2-3. データベース作成方法を選択

データベース作成方法を選択という項目はフル設定を選択します。

2-4. テンプレート設定

テンプレートは無料利用枠を選択しておきます。

2-5.可用性と耐久性設定

可用性と耐久性は、今回はとりあえず実装するのが目的なのでデフォルトの シングル AZ DB インスタンスデプロイ (1 インスタンス)のままで良いです。

2-5. 設定

エンジンバージョン

MySQL 8.x

等のように8系のバージョンであれば良いです。

DBインスタンス識別子

これはAWS上でRDSを識別するための名前です。

今回は、

myspringboot-db

にしておきます。

マスターユーザー名

好きな文字列を入れてください。

認証情報管理

セルフマネージドのままで良いです。

マスターパスワード

好きな文字列を入力してください。

2-6. インスタンスの設定

インスタンスタイプ

db.t4g.micro

のままで良いです。

2-7. ストレージ

デフォルトの最小サイズのままで良いです。

2-8. 接続

コンピューティングリソース

EC2 コンピューティングリソースに接続

を選択します。

EC2 インスタンス

EC2で作成したSpring Boot用のインスタンスのIDを選択します。

DB サブネットグループ

自動セットアップ

を選択します。

パブリックアクセス

デフォルトのなしのままで良いです。

VPC セキュリティグループ (ファイアウォール)


新規作成を選択します。

### 新しい VPC セキュリティグループ名

今回は、

```text
rds-mysql-sg

としておきます。

追加設定

データベースポートは3306に設定しておきます。

2-9. モニタリング

何もせずデフォルトのままで良いです。

2.10

ここまで出来たらいったんデータベースの作成をクリックして登録します。

3. RDSのセキュリティーグループの設定

データベースの作成をした後、

データベース
    ↓
作成したデータベース名
    ↓
接続とセキュリティ
    ↓
接続されたコンピューティングリソース
    ↓
表示されているセキュリティグループ
    ↓
インバウンドルール
    ↓
インバウンドルールを編集

を選択していきます。

編集画面で、

タイプ:MySQL/Aurora
ポート:3306
ソース:カスタム
ソース:EC2のセキュリティグループ

をそれぞれ選択・入力します。

EC2のセキュリティグループ

EC2
  ↓
インスタンス
  ↓
作成しているインスタンス
  ↓
セキュリティ
  ↓
セキュリティーグループ

に記載されている

sg-xxxxxxxxxxxxxxxxx

のような文字列です。

設定ができたらルールの保存をクリックします。

うまくできているか確認

EC2では、

EC2 → インスタンス → 対象EC2 → ネットワーキング → VPC ID

RDSでは、

RDS → データベース → 対象RDS → 接続とセキュリティ → VPC

をそれぞれ確認します。

例えば両方とも、

vpc-0123456789abcdef

となっていればOKです。

4. EC2へMySQLクライアントを実装する

EC2にSSH接続して、MySQLクライアントからRDSへログインできるか確認します。

4-1. MySQLクライアントをインストールする

ローカルPCでEC2にSSH接続します。

ssh -i springboot-key.pem ubuntu@<EC2のパブリックIP>

まずパッケージ情報を更新します。(Ubuntuの場合)

sudo apt update

その後、MySQLクライアントをインストールします。

sudo apt install mysql-client

その後、

mysql --version

でインストールできているか念のため確認します。

4-2. RDSのエンドポイントを確認する

AWSコンソールで、

Aurora and RDS → データベース → 対象RDS → 接続とセキュリティ → エンドポイント

を開き、エンドポイントを確認します。

myspringboot-db.xxxxxxxxx.ap-northeast-1.rds.amazonaws.com

のようなエンドポイントの値があるので、これを控えておきます。

4-3. EC2からRDSへ接続する

EC2上で次のコマンドを実行します。

mysql -h <RDSのエンドポイント> -P 3306 -u <マスターユーザー名> -p

例えば、

mysql -h myspringboot-db.xxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u admin -p

のような記述をします。

実行途中Enter password:などが表示されるのでRDS作成時のパスワードを入力します。
パスワードは画面には表示されませんが、そのまま入力してEnterを押してください。

成功すると、次のような表示になります。

mysql>

この状態になれば、

EC2
 ↓
RDS MySQL

のネットワーク接続が正常にできています。

もしすでにデータベースを作成している場合は、

SHOW DATABASES;

を実行するとデータベース一覧が表示されます。

終了する場合は、

exit;

を実行します。

5. MySQLにデータベース・テーブルを作成

ここでは、Spring Bootが使用するデータベースとテーブルを作成します。

5-1. EC2からRDSへ接続する

EC2へSSH接続した後、RDSのMySQLへ接続します。

mysql -h <RDSのエンドポイント> -P 3306 -u <マスターユーザー名> -p

具体的なやり方は4章を確認してください。

5-2. 現在のデータベースを確認する

SHOW DATABASES;

を実行すると

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

のような表示があります。

5-3. Spring Boot用のデータベースを作成する

SQLクライアント上で以下を実行します。

CREATE DATABASE myspringboot
CHARACTER SET utf8mb4
COLLATE utf8mb4_0900_ai_ci;

utf8mb4は、MySQLなどのデータベースで利用される最大4バイトのUTF-8文字コードセットで、絵文字や一部の特殊な漢字などを正確に保存できます。

utf8mb4_0900_ai_ciは、MySQL 8.0以降で標準採用されている、大文字・小文字やアクセント記号を区別しない照合順序(文字の比較・並び替えルール)です。

また、myspringbootが実装用データベース名です。

再び

SHOW DATABASES;

を実行して

myspringboot

が表示されればOKです。

5-4. 使用するデータベースを選択する

次に、

USE myspringboot;

を実行すると、

Database changed

と表示されます。

以降のSQLコマンドはmyspringbootに対して実行されます。

5-5. H2のテーブル構造を確認する

H2に存在するテーブルと同じ構造をMySQL側にも用意する必要があります。例えば現在のSpring Bootプロジェクトに、

src/main/resources/schema.sql

があり、

CREATE TABLE sample (
    id VARCHAR(50) PRIMARY KEY,
    str VARCHAR(100),
);

となっているのであれば、これを基準にRDSのMySQL側のテーブルを作ります。

5-6. MySQLにテーブルを作成する

先ほどの例の場合、

CREATE TABLE sample (
    id VARCHAR(50) PRIMARY KEY,
    str VARCHAR(100),
);

を実行して作成をします。成功すると、

Query OK

と表示されます。

5-7. テーブルが作成されたことを確認する

SHOW TABLES;

を実行して、

+------------------------+
| Tables_in_myspringboot |
+------------------------+
| sample                 |
+------------------------+

と表示されれば成功です。また、

DESCRIBE sample;

を実行すると、

+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | varchar(50) | NO   | PRI | NULL    |       |
| str   | varchar(50) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

のように、テーブルの構造を確認できます。

5-8. 必要であれば初期データを登録する

H2でdata.sqlなどを使用して初期データを入れている場合は、MySQLにも必要なデータを用意します。
例えば

INSERT INTO sample (id, str)
VALUES('1', 'こんにちは');

等を実行し登録します。その後、

SELECT * FROM sample;

で確認します。

現在の構造は

RDS MySQL
│
└── myspringboot
      ├── sample
      ├── sample2
      └── sample3

のようになっています。

6. Spring BootにMySQL JDBCドライバを追加

Spring BootからRDSのMySQLへ接続できるように、MySQL JDBCドライバをMavenの依存関係に追加します。

6-1. pom.xmlを編集する

pom.xml

を開きます。

<dependencies> の中に次を追加します。

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

H2の<dependency>は削除しなくて問題ないです。

6-2. Mavenの依存関係を更新する

ターミナルから、

mvnw clean package

を実行します。もし、

BUILD SUCCESS

という表示があれば成功です。これでSpring Bootアプリ内に、

Spring Boot
     │
     ↓
MySQL JDBC Driver
     │
     ↓
MySQL

という接続に必要なドライバを組み込める状態になりました。

7. Spring Bootの本番用設定を作成

ローカル開発ではH2、本番のEC2ではRDS MySQL を使い分けられるようにします。

7-1. application.ymlを作成・編集する

まず、src/main/resources配下を次のようにします。

src/main/resources
├── application.yml
└── application-prod.yml

application.yml は開発用、application-prod.yml は本番用として使います。

application.ymlはすでに環境に合わせて作成していると思いますので、そのまま編集する必要はありません。

作成したapplication-prod.yml に以下の本番用MySQL設定を書きます。

spring:
  datasource:
    url: jdbc:mysql://<RDSのエンドポイント>:3306/myspringboot
    username: <MySQLのユーザー名>
    password: <MySQLのパスワード>
    driver-class-name: com.mysql.cj.jdbc.Driver

ただし、この状態ではGitHubなどにPushした場合パスワードなども公開されてしまいます。
そのため、

spring:
  datasource:
    url: jdbc:mysql://${DB_HOST}:3306/${DB_NAME}
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver

のように記述します。このようにすることで、Spring Bootは

DB_HOST
DB_NAME
DB_USERNAME
DB_PASSWORD

というLinuxに保存した環境変数ファイルから値を取得するようになります。
Spring Bootが正しく環境編集を取得・代入をするための設定は後述します。

7-2. EC2で本番Profileを指定する

application-prod.yml は、普通に起動しただけでは使用されません。

EC2上で以下を実行します。

sudo nano /etc/systemd/system/myspringboot.service

ExecStarを以下のように変更します。

java -jar MySpringBoot-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod

後半の部分でprod Profileを指定して起動するようにしています。

8. DB接続情報を、EC2側に環境変数として保存し、systemd経由でSpring Bootへ渡す

今回は、myspringboot.service にパスワードを直接書くのではなく、環境変数用のファイルを分離する方法を用います。

8-1. 環境変数を保存するディレクトリを作る

EC2上で以下を実行します。

sudo mkdir -p /etc/myspringboot

続いて環境変数ファイルを作ります。

sudo nano /etc/myspringboot/myspringboot.env

8-2. DB接続情報を記述する

次のように記述します。

DB_HOST=<RDSのエンドポイント>
DB_NAME=myspringboot
DB_USERNAME=<DBユーザー名>
DB_PASSWORD=<実際のRDSのパスワード>

記述した内容を確認する場合は以下を実行します。

sudo cat /etc/myspringboot/myspringboot.env

入力したら

Ctrl + O
↓
Enter
↓
Ctrl + X

の順にコマンドを実行して保存します。

8-3. ファイルの権限を制限する

このファイルはパスワードが平文で入っているので誰でも読める状態にはしません。

所有者を設定します。

sudo chown root:ubuntu /etc/myspringboot/myspringboot.env

root:ubuntu: ユーザー:グループ の形式で指定しています。
ユーザー名はsystemedのサービスファイルで指定しているUser名で良いです。

続いて、

sudo chmod 640 /etc/myspringboot/myspringboot.env

を実行します。こうすることで、

root ユーザー  : 読み書き可能
ubuntu グループ: 読み取りのみ可能
その他のユーザー: アクセス不可

となります。

8-4. systemdのサービスファイルを編集

/etc/systemd/system/myspringboot.service

を編集します。

sudo nano /etc/systemd/system/myspringboot.service

を実行し、サービスファイルを以下のようにします。

[Unit]
Description=My Spring Boot Application
After=network.target

[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu

EnvironmentFile=/etc/myspringboot/myspringboot.env

ExecStart=/usr/bin/java -jar /home/ubuntu/MySpringBoot-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod

Restart=always

[Install]
WantedBy=multi-user.target

重要なのは、

EnvironmentFile=/etc/myspringboot/myspringboot.env

です。これによってsystemdが、

myspringboot.env
       ↓
環境変数を読み込む
       ↓
Spring Bootを起動して変数を代入

という処理をしてくれます。例えば、

${DB_HOST}
    ↓
myspringboot-db.xxxxx.ap-northeast-1.rds.amazonaws.com

のようにSpring Bootが${DB_HOST}などを環境変数に置き換えます。

8-5. systemdに変更内容を読み込ませる

serviceファイルを変更したので、

sudo systemctl daemon-reload

を実行します。

9 新しいJARを作成・EC2へ転送する

JARの更新手順は以下のリンクを参照してください。
EC2で公開したSpringBoot Webアプリを更新する方法

EC2にJARを転送出来たら次章へ進みます。

10. RDS MySQLへの接続をテストする

最終ステップです。実際にSpring Boot を起動して動作テストをおこないます。

10-1. Spring Bootを起動する

sudo systemctl start myspringboot

または

sudo systemctl restart myspringboot

を実行します。実行したら、

sudo systemctl status myspringboot

で確認します。

10-2. prod Profile が有効になっているか確認する

ログを確認します。

sudo journalctl -u myspringboot -n 100

Spring Boot の起動ログに、

The following 1 profile is active: "prod"

のような記載があれば prod Profileが有効になっています。

つまり、application-prod.yml が使われています。

ログが非常に長いですが、(おそらく)最後に記載されているSpring Bootの起動ログのみ見ればよいです。

10-3. ブラウザからWebアプリを確認する

最後にWebアプリのURLへアクセスしてみます。

DBを利用する機能を確認します。

CRUDを試して問題がなければ作業完了です。

10-4. RDS側でもデータを確認する

念入りに成功しているか確認したい場合は、RDS側でもデータが更新などできているか確認するのが良いです。

EC2からMySQLへ接続します。

mysql -h <RDSエンドポイント> -P 3306 -u <ユーザー名> -p

ログイン後、

USE myspringboot;

SHOW TABLES;

SELECT * FROM sample;

等を実行します。

Webアプリから登録したデータがRDS側にも存在すれば、H2ではなくRDS MySQLを実際に使用していることが確認できます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?