プライベートサブネット内に作成したAurora PostgreSQLに踏み台EC2を用いて接続する

# はじめに

プライベートサブネット内にAurora PostgreSQLを作成した際に、プライベートな接続を保ちながらSQLコマンドを使えると何かと便利だと考えたため、踏み台EC2を用いて接続することにしました。
ただ、少々手順が複雑になってしまったため、忘備録の意味もかねてその手順を残します。
今回は、AWSを全く触ったことがない方向けに記述するつもりですので、少々説明が細かくなりすぎてしまうかもしれませんが、ご了承ください。
#接続全体イメージ
以下のような構成イメージで作成します。
パブリックサブネット内にEC2を作成してもよかったのですが、より堅牢な構成を目指すためにクライアントVPNエンドポイントをEC2の前に挟み、EC2をプライベートサブネット内に入れることにしました。
![プライベートAuroraへの接続全体図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/db1cfe14-e3e1-bea8-22eb-7c7cc2a44134.png)
# 事前準備
#### アプリ
以下のアプリを今回は使用します。OpenVPN ベースのクライアントアプリケーションやターミナルエミュレーターがあればインストールは不要になります。
・AWS Client VPN( https://aws.amazon.com/jp/vpn/client-vpn-download/ )
・Teraterm( https://ja.osdn.net/projects/ttssh2/releases/ )
#### 環境
Linuxコマンドが使えれば何でもよいですが、私は以下環境を用いました。
・Ubuntu 20.04.1 LTS
# 実施手順
1. VPC・サブネット・セキュリティグループ・ルートテーブル作成
2. 証明書作成・登録
3. クライアントVPNエンドポイントの作成
4. VPNへのテスト接続
5. EC2作成
6. インターネットゲートウェイ作成・紐づけ
7. EC2内にPostgreSLQをインストール
8. Aurora Postgres作成・接続

## 1. VPC・サブネット・セキュリティグループ・ルートテーブル作成
セキュリティ周りのVPCを作成していきます。RDSやEC2を作成する前に入れ物を正しく作っておき、外部からの不正なアクセスを防ぎます。
![VPC_サブネット_セキュリティグループ作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/fef92e45-3fdd-63c6-7fcb-4a782e0b6e97.png)
まずは任意のCIDRでVPCを作成しましょう。
![スクリーンショット 2021-02-11 235715.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/c5d4725e-8c96-9b9f-9e2e-fd4a517d2cc0.png)
先ほど作成したVPCに紐づく形でサブネットを作成していきましょう。Auroraに紐づく予定のサブネットを別々のアベイラビリティーゾーンで２個(※)、EC2に紐づく予定のサブネットを１個作成します。
（※ RDSに紐づくサブネットグループは、２か所以上のアベイラビリティゾーンにまたがっている必要があります。）
![スクリーンショット 2021-02-12 000640.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/4709424a-2639-5497-b0a7-83336ed03bf1.png)
セキュリティグループはSSH接続を許すものとpsql接続を許すものをそれぞれ作成します。SSH接続、psql接続ができるようにインバウンドルールをそれぞれ設定します。
![スクリーンショット 2021-02-12 001522.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/7f444cbf-5c9c-500e-8fc2-6f993088e828.png)
![スクリーンショット 2021-02-12 001656.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/4081339f-7147-da58-4662-be9f450e023a.png)
ルートテーブルはEC2用とAurora用をそれぞれ作りましょう。任意の名前で二つルートテーブルを作成したら、サブネット関連付けの編集でEC2用のサブネット、Aurora用の２つのサブネットと関連付けます。
![スクリーンショット 2021-02-12 121351.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/61f3d31d-b532-b572-790c-3025bfb70302.png)
## 2. 証明書作成・登録
クライアントVPNエンドポイントへの接続の認証は、今回は証明書による相互認証を用います。
まずは、証明書の作成をLinuxコマンドで行います。

```
# Open VPNソースのダウンロード、ディレクトリ移動
$ git clone https://github.com/OpenVPN/easy-rsa.git
$ cd easy-rsa/easyrsa3

# PKI環境の初期化
$ ./easyrsa init-pki

# 認証機関 (CA) を構築
# Common Nameは任意の名前を入力します。
$ ./easyrsa build-ca nopass

# サーバー証明書とキーを生成
$ ./easyrsa build-server-full server.domain.com nopass

# クライアント証明書とキーを生成
$ ./easyrsa build-client-full client1.domain.tld nopass
```
これで、サーバー証明書の作成が終わりました。
続いて、この証明書をACM(AWS Certificate Manager)にインポートします。AWS CLI(※)でインポートする場合は以下のコマンドを実行してください。
マネジメントコンソールから直接インポートすることも可能です。
※ AWS CLI 参考
インストール: https://qiita.com/SSMU3/items/ce6e291a653f76ddcf79
設定: https://qiita.com/SSMU3/items/ce6e291a653f76ddcf79

```
# サーバー証明書とキー、およびクライアント証明書とキーをcert_folderフォルダにコピーして移動
$ mkdir ~/cert_folder/
$ cp pki/ca.crt ~/cert_folder/
$ cp pki/issued/server.domain.com.crt ~/cert_folder/
$ cp pki/private/server.domain.com.key  ~/cert_folder/
$ cp pki/issued/client1.domain.tld.crt ~/cert_folder
$ cp pki/private/client1.domain.tld.key ~/cert_folder/
$ cd ~/cert_folder/

# サーバー証明書とキーをインポート
$ aws acm import-certificate --certificate fileb://server.domain.com.crt --private-key fileb://server.domain.com.key --certificate-chain fileb://ca.crt --region ap-northeast-1

# クライアント証明書とキーをインポート
$ aws acm import-certificate --certificate fileb://client1.domain.tld.crt --private-key fileb://client1.domain.tld.key --certificate-chain fileb://ca.crt --region ap-northeast-1
```
## 3. クライアントVPNエンドポイントの作成
クライアントVPNエンドポイントを作成します。任意のCIDRを入力し、認証情報で相互認証の使用を選択します。
サーバー証明書 ARN・クライアント証明書 ARNは、先ほどACMに登録した証明書が選択できるためそれぞれ選択します。
![スクリーンショット 2021-02-12 004002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/7b3ca0c7-e18b-d337-d133-99423c38b1aa.png)
作成したエンドポイントはVPNと関連付けなければ、VPNの中に入れません。VPN・サブネットとの関連付けを行います。サブネットはEC2用に作成したものに関連付けます。
![スクリーンショット 2021-02-12 005450.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/8cf42730-6b68-926b-89ae-980fd2e12ceb.png)
VPNアクセスをクライアントに承認するために、受信の承認ルールを作成します。アクセスを有効にする送信先ネットに、接続するVPCのCIDR全体を指定し「すべてのユーザーにアクセスを許可する」を選択します。
![スクリーンショット 2021-02-12 005504.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/909c2242-cc3e-3b07-5751-f813570075e2.png)
## 4. VPNへのテスト接続
EC2を作成する前にクライアントVPNエンドポイントへの接続の設定を行います。まず、設定ファイルをダウンロードします。
![スクリーンショット 2021-02-12 012152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/91fa4426-5874-ad57-0173-59d9899e2acf.png)
続いて、ダウンロードした設定ファイルの末尾に、手順2で作成した証明書の内容を以下の通りに追記します。

```
<cert>
※client1.domain.tld.crt(-----BEGIN CERTIFICATE-----～-----END CERTIFICATE-----)の内容※
</cert>

<key>
※client1.domain.tld.key（-----BEGIN PRIVATE KEY-----～-----END PRIVATE KEY-----）の内容※
</key>
```
記入後の設定ファイルをプロファイルとしてアプリ:AWS VPN Client に登録します。
アプリを起動し、ファイル→プロファイルの管理→プロファイルの追加→VPN設定ファイルを選択し登録します。
成功していれば登録したプロファイルを使用し、下図のようにVPN接続ができるようになっているはずです。
![クライアントVPNエンドポイント作成まで.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/785d021e-9bcb-9ee8-505d-0406bea0686e.png)
## 5. EC2作成
次にEC2の作成を行います。今回は、Amazon Linux2の無料利用枠を使用していきます。
![スクリーンショット 2021-02-12 014437.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/d8c80cce-db27-dc5e-b119-27417548fb67.png)
ステップ３:インスタンスの詳細の設定にて

ネットワーク: 作成したVPC
サブネット: EC2用に作成したサブネット
自動割り当てパブリックIP: 有効

をそれぞれ選択します。
![スクリーンショット 2021-02-12 014741.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/59be4755-6e01-48c6-d470-56c9d0108e54.png)
ステップ6: セキュリティグループの設定ではEC2用に作成したセキュリティグループを選択します。
![スクリーンショット 2021-02-12 014834.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/c3b178fc-976f-1352-0818-ec423d5b8a8f.png)
作成時、キーペアは必ずダウンロードし、大切に保存してください。
## 6. インターネットゲートウェイ作成・紐づけ
現状このような構成です。
![EC2作成まで.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/d664950b-8b75-b75e-5e8e-2ab82436a7af.png)
このままではEC2内部Amazon linux2でSQLコマンドが使えません。つまり、EC2にPostgreSQLをインストールする必要があります。
そのために、一旦インターネットゲートウェイをEC2用のサブネットに紐づけ、EC2がPostgreSQLをダウンロード・インストールできるようにします。
![EC2にインターネットゲートウェイ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/55a162c1-a1f3-3f87-609e-ab15f32ed1b7.png)
VPCのメニューからインターネットゲートウェイを選択し、作成します。
作成したインターネットゲートウェイにVPCをアタッチします。
![スクリーンショット 2021-02-12 021517.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/f04b5e1d-8e6e-45ea-f8e9-7cd8b104c631.png)
続いてEC2用に作成したルートテーブルのルートの編集からインターネットゲートウェイをターゲットに指定し追加します。
![スクリーンショット 2021-02-12 023050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/b54be3c4-b15f-ad1a-6ce9-e34e76257c08.png)
これで、EC2がインターネットにつながるようになりました。
## 7. EC2内にPostgreSLQをインストール
EC2に接続するためにAWS VPN Client を用いてクライアントVPNエンドポイントに接続しておきます。
Tera Teamを起動し、プライベートIPアドレスにSSH接続します。EC2のユーザー名を「ec2-user」、認証方式を「RSA/DSA/ECDSA/ED25519鍵を使う」にし、手順5、EC2作成時のキーペアを指定します。
![スクリーンショット 2021-02-12 023931.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/b26159b0-54a4-372f-5128-f2404d48c7c5.png)
無事にEC2が起動できると以下のような画面になります。
![スクリーンショット 2021-02-12 030657.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/7c2a431d-35c0-349c-eb4c-754d1ea82c3d.png)
今回はPostgreSQL12をインストールします。2021年2月現在、Amazon Linux2は公式でPostgreSQL12をサポートしていません。そのため、PostgreSQLが提供するyumリポジトリをインストールする必要があります。インストール後、ファイルを書き換え、PostgreSLQ12をインストールします。

```
# PostgreSQL用yumのインストール
$ sudo rpm -ivh --nodeps https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# 「/etc/yum.repos.d/pgdg-redhat-all.repo」ファイルの書き換え
$ sudo sed -i 's/\$releasever/7/g' /etc/yum.repos.d/pgdg-redhat-all.repo

# PostgreSQLのインストール
$ sudo yum install -y postgresql12 postgresql12-server
```
これにてインストールは完了です。
これからの作業は、インターネットにつなぐ必要がないため、ルートテーブルからインターネットゲートウェイを削除しましょう。
![postgresqlインストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/fdd15e4b-08c3-8c7b-2af9-e5234f561feb.png)
## 8. Aurora Postgres作成・接続
ではいよいよRDS Aurora PostgreSQL を作成していきましょう。
Amazon RDS のサブネットグループを選択し、 DB サブネットグループを作成を選択します。サブネットグループにはAurora用に作成したサブネット２個を追加します。
![スクリーンショット 2021-02-12 025736.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/218ddcf4-12d7-6327-00d5-dd6fd90ffd60.png)
データベースを作成します。VPC、サブネットグループ、セキュリティグループはAurora用に作成したものを、パブリックアクセスは「なし」で作成してください。ほかの項目は任意に設定してください。
これで全ての手順は終了です。
作成したDBのエンドポイントを用いて、EC2からAuroraに接続してみましょう。

```
psql --host=<エンドポイント> --port=5432 --username=<ユーザー名> --password --dbname=<データベース名>
```
以下のようになれば成功です。
![スクリーンショット 2021-02-12 030753.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674265/c3d52cb5-e71e-862d-01bf-3d05fb02ea16.png)

# 参考URL
以下サイトを参考にさせていただきました。ありがとうございました。

・AWSのEC2からRDSに接続してmySQLを操作。EC2踏み台サーバー構築メモ
https://photo-tea.com/p/aws-ec2-to-rds-connection/

・AWS Client VPNを試してみる
https://fu3ak1.hatenablog.com/entry/2020/08/12/145243

・[初心者向け]VPC作成からEC2インスタンス起動までを構成図見ながらやってみる（その1）
https://dev.classmethod.jp/articles/creation_vpc_ec2_for_beginner_1/

・ルートテーブルシナリオの実際の構築手順（AWSの設定編）
https://bcblog.sios.jp/construction-procedure-of-routetablescenario-aws/

・【Ansible】PostgreSQL 12をAmazon Linux 2にインストールし、Ansible Playbook化する【PostgreSQL】
https://qiita.com/tmiki/items/00d22edc6a554f61bd04

# 最後に
拙い文章ながらここまで読んでいただきありがとうございました。
何かご指摘があればご気軽にコメントください。