10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

EC2からプライベートなRDSに接続する方法

Last updated at Posted at 2023-10-23

内容

  • RDSを立ち上げてEC2からDB操作する手順をまとめています
  • RDSはプライベートサブネットに設定し、外部からのアクセスができないようにします
  • パブリックサブネットにあるEC2からRDSにアクセスしてDBを操作します
  • webサーバーで画面に表示したページからDBを操作します

↓完成形
image.png

↓の記事の続きとなっています。
webサーバーから立ち上げたい方はご覧ください。

目次

ネットワークの作成

まずはRDSを設置するネットワークを作成します。
今回の要件としては、「外部からのアクセスを制限する」です。
外部からのアクセスというのはインターネットからのアクセスのことです。
前回立ち上げたEC2のパブリックサブネットはインターネットゲートウェイと通信ができる、つまりインターネットからアクセスすることができました(なのでローカルからダイレクトでssh接続できるのです)。
image.png

しかしDBは外部からアクセスされると、データが不正に操作される恐れがあるため、プライベートなネットワークに置くことがセキュリティ上推奨されています(Webサーバーもそうなのですが今回は無視します)。

そのため、AWSでプライベートなネットワークを実現させます。
そのためにはプライベートサブネットというものを作成します。
image.png

プライベートサブネットの作成

プライベートサブネットを作成します。
VPC > Subnets > サブネットを作成をクリックします。
スクリーンショット 2023-10-23 19.34.41.png

後ほどご説明しますが、RDSを立ち上げるために、異なるアベイラビリティゾーンにサブネットを1つずつ作成します。
すでに作成しているサブネットのCIDRに被らないように設定します。

↓サブネット1つ目
image.png

↓サブネット2つ目
image.png

作成したサブネットにルートテーブルを設定します。
パブリックサブネットを作成したときは、インターネットゲートウェイへの通信もルートテーブルに設定していました。
しかし今回はプライベートにしたいので、インターネットゲートウェイへの通信は設定せずに作成します。
image.png

ルートテーブルを作成すると、「明示的な関連付けがないサブネット」に先ほど作成した2つのサブネットが表示されます。
これら2つを選択して「サブネットの関連付けを編集」します。
68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323933353730302f31326130386461662d393530302d333034312d386161382d6361666663323436643365322e706e67.png

対象のサブネット2つを選択し「関連付けの保存」をします。
68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323933353730302f64326166663831322d326431332d313165342d646132632d3765313935326164376539372e706e67.png

これでインターネットに繋がらないプライベートサブネットが作成できました。
次にこれらのサブネットをサブネットグループにまとめます。

サブネットグループとは、RDSインスタンスが使用するサブネットのことで、
RDSインスタンスは複数のアベイラビリティゾーンのサブネットにまたがって作成する必要があります。
一方のアベイラビリティゾーンなどに異常が起きた時に、もう一方のアベイラビリティゾーンでインスタンスを立ち上げることで、サービスの停止を防ぐのです。(冗長化と言います)
image.png

今回はRDS用に2つのプライベートサブネットを作成したので、これらをサブネットグループとします。

RDSのダッシュボードから「サブネットグループ」を選択します。
スクリーンショット 2023-10-23 19.39.57.png

先ほど作成したサブネットを選択します。
サブネットグループの作成には、複数のアベイラビリティゾーンからサブネットを1つ以上選択する必要があります。
スクリーンショット 2023-10-23 19.44.25.png

これでプライベートサブネットで構成されたサブネットグループが作成されました。

セキュリティグループの作成

続いてセキュリティグループを作成します。
RDSにもセキュリティグループを設定するのですが、今回はパブリックサブネットのEC2からのアクセスだけを許可するようにします。
image.png

RDS用のセキュリティグループを設定します。
後にEC2から接続するので、EC2にアタッチされているセキュリティグループからのアクセスを許可します。
スクリーンショット 2023-10-23 20.55.27.png
これでパブリックサブネットに設置したEC2からのみアクセスすることができました。

RDSを立ち上げる

パラメータグループの作成

パラメータグループを作成します。
パラメータグループとは、RDSの設定情報をテンプレートとして保存するもので、
同じパラメータグループに属するRDSインスタンスにまとめて設定を反映させることができます。
image.png

後ほどRDSインスタンスを立ち上げるときに選択します。

オプショングループの作成

オプショングループも、グループに属するインスタンスにオプションをまとめて反映させることができるものです。
image.png

これもRDSインスタンスを立ち上げる時に選択します。

RDSインスタンスの作成

いよいよRDSを立ち上げます。
RDSダッシュボードから「データベースの作成」をクリックします。

「標準作成」を選択して今回はエンジンを「MySQL」にします。
image.png

今回はテスト用なので「無料利用枠」を選択します。
image.png

「DBインスタンス識別子」, 「マスターユーザー名」, 「パスワード」はご自身で決めてください。
DBに接続をするときに必要になります。
image.png

DBインスタンスクラスとはいわばDBのスペックで、スペックが良いほど料金も高くなります。
今回はテスト用なので安い「db.t3.micro」を選択します。
image.png

ネットワークは先ほど作成した、VPC内のプライベートサブネットを指定します。
image.png

セキュリティグループは先ほど作成した、EC2からのアクセスのみを許可したものを指定します。
image.png

そのほかの設定はデフォルトでOKです。
これで「データベースの作成」をすると、数分後にRDSインスタンスが立ち上がります。
立ち上がったらWEBサーバーからアクセスしてみましょう。

EC2からアクセスする

EC2から接続する

立ち上げたRDSにEC2から接続します。
まずはEC2にssh接続します。

~ %ssh -i ~/.ssh/test-key.pem ec2-user@[EC2のパブリックIP]

MySQLコマンドをインストールします

[ec2-user@ip-10-0-0-102 ~]$ sudo yum -y install mysql
Last metadata expiration check: 0:03:43 ago on Mon Oct 23 11:17:43 2023.
No match for argument: mysql
Error: Unable to find a match: mysql

おっとエラーが起きました。
どうもAmazon linux 2023でこのエラーが起きるようです。
そんな時は

[ec2-user@ip-10-0-0-102 ~]$ sudo dnf -y localinstall https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm
[ec2-user@ip-10-0-0-102 ~]$ sudo dnf -y install mysql mysql-community-client

とします。
正直何しているかわかりませんがスルーします。
そして再度mysqlコマンドのインストールを試みます。

[ec2-user@ip-10-0-0-102 ~]$ sudo yum install mysql -y
Last metadata expiration check: 0:00:06 ago on Mon Oct 23 11:22:09 2023.
Package mysql-community-client-8.0.34-1.el9.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!

無事インストールができました!
ではRDSに接続しましょう。
EC2に接続した状態でmysql -h [エンドポイント] -P 3306 -u admin -pと叩きます。

[ec2-user@ip-10-0-0-102 ~]$ mysql -h [エンドポイント] -P 3306 -u admin -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 8.0.33 Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

接続に成功しました!

ついでにテーブルを作成しておきましょう。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| testdb             |
+--------------------+
5 rows in set (0.01 sec)

mysql> use testdb;
Database changed

mysql> CREATE TABLE Post ( post_id INT PRIMARY KEY AUTO_INCREMENT, post VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.03 sec)

testdbというデータベースに↓のようなPostテーブルを作成しました。

CREATE TABLE Post (
post_id INT PRIMARY KEY AUTO_INCREMENT,
post VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
);

これで準備は整いました。
ではEC2のウェブサーバーからこのデータベースに接続しましょう。

ウェブサーバーからDBを操作する

今回はPHPでデータベースを操作します。
なのでウェブサーバーのディレクトリインデックスをPHPファイルに変えておきましょう。

[ec2-user@ip-10-0-0-102 conf]$ sudo vi /etc/httpd/conf/httpd.conf

...

<IfModule dir_module>
    DirectoryIndex index.php index.html
</IfModule>

...

そしてindex.phpファイルを↓のようにします
※データベースの接続情報をベタかきしていますが、セキュリティガバガバなので、実際は.envに書くなどしましょう。

[ec2-user@ip-10-0-0-102 ~]sudo vi /var/www/html/index.php
<?php
$dsn = "mysql:host=[エンドポイント];dbname=[データベース名(今回はtestdb)]";
$username = "ユーザー名(今回はadmin)";
$password = "パスワード";
$dbh = new PDO($dsn, $username, $password);

if ($post_message) {
    $query = "INSERT INTO post (post) VALUES ('" . $post_message  . "')";
    $stmt = $dbh->query($query);
}

// クエリの実行
$query = "SELECT post FROM post ORDER BY created_at DESC";
$stmt = $dbh->query($query);
$post_data = $stmt->fetchAll(PDO::FETCH_BOTH);
?>
<!DOCTYPE html>
<html lang="en">
<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>sqs</title>
</head>
<body>
    <form action="" method="post">
        <input name="post">
	<button>送信</button>
    </form>
    <p>↓ここにメッセージが表示されます↓</p>
    
    <?php foreach($post_data as $post): ?>
    <p><?php echo($post['post']); ?></p>
    <?php endforeach; ?>
</body>
</html>

php-mysqlパッケージをインストールします。

[ec2-user@ip-10-0-0-102 html]$ sudo yum install php-mysqlnd

これでWEBサーバーにブラウザからアクセスしてみましょう。

EC2のパブリックIPをブラウザに打ち込むとページが表示されます。
メッセージを送信すると...
image.png

データベースに保存されました!!
image.png

無事RDSインスタンスのDBの操作を行うことができました!!

10
11
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
10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?