LightsailからデフォルトVPC以外のRDSへ接続してみる

2022.05.03

いわさです。

Webサーバーを構築する際にLightsailからまず始めるケースあると思います。
今回、別のVPCに存在しているRDSへ接続したいシーンがありました。

Lightsailの本格運用にあたってEC2へ移行出来ると柔軟性が増えると思います。

しかし、何らかの制約でWebサーバーはLightsailを使い続ける必要があった場合などを想定して、LightsailからVPCのRDSへ接続をしてみました。

VPCピアリングとプライベートリンク

まず、LightsailインスタンスからVPCリソースに接続したい場合に真っ先に思いつくのはVPCピアリング機能です。
しかし、LightsailのVPCピアリング機能はひとつ制限があって、同一リージョンのデフォルトVPCとしかピアリング接続を構成出来ません。

そこで、PrivateLink機能を使って、デフォルトVPC上に別VPCのRDSへのエンドポイントを作成してみることにしました。

以下のようなイメージを構築してみます。

やってみる

独自のVPCにRDSを作成済みです。
パブリックアクセスをOFFにしているMySQLです。

Lightsailインスタンス作成

まずは、Lightsailインスタンスを作成します。 なんでも良さそうですが、最終的にMySQLに接続するのでLAMPかWordPressあたりのイメージを選んでおくとMySQLクライアントのセットアップ不要で検証出来そうな気がします。

VPCピアリング作成

Lightsailのアカウントメニューのアドバンスドタブ内でVPCピア接続を有効化出来ます。
チェックボックスにチェックするだけで、どのLightsailインスタンスとかの制御はないですね。特定インスタンスに制限したい場合はVPCエンドポイントのセキュリティグループでソースIPアドレスで制限することになりそうです。

LightsailでVPCピア接続有効化後に、VPCコンソールでピアリング接続を確認してみましょう。
ピアリングが作成されていますね。リクエスタの情報を見てみると、Lightsailはどうやら実態は別のAWSアカウントに存在しているようですね。

エンドポイントサービス作成

今回はRDSへの接続をNLB経由で行います。
まずはNLB用にターゲットグループを作成します。
ターゲットタイプにRDSを選択することは出来ないので、ターゲットは「IPアドレス」になります。これによる注意点は最後に少し触れています。

RDSインスタンスのIPアドレスが必要です。
ENIのプライベートIPアドレスを使いました。RDSの接続エンドポイントを名前解決したときのIPアドレスでもあります。(シングルAZ)

$ nslookup database-1.cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com
Server:        192.168.11.1
Address:    192.168.11.1#53

Non-authoritative answer:
Name:    database-1.cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com
Address: 10.0.149.166

IPアドレスをターゲットに追加します。
ポートはMySQLの接続を行うのでここでは3306を使っています。

NLBのTCP3306のターゲットに用意したターゲットグループを選択します。

最後に、用意したネットワークロードバランサーをエンドポイントサービスとして登録することで、エンドポイントから参照出来るようになります。
VPCコンソールの「エンドポイントサービス」から新規作成し、先程作成したNLBを登録します。

サービス名が表示されるのでコピーしておきます。
このあと使います。

エンドポイント作成

NLBがサービスとして登録されたので、デフォルトVPC上にエンドポイントを作成することでNLBにアクセス出来るようになります。
同じくVPCコンソールからエンドポイントの作成を行います。

「その他のエンドポイントサービス」から、先程作成したエンドポイントサービスのサービス名を入力しサービスの検証を行います。

あとはアタッチするVPCを選択します。
今回はLightsailのVPCピアリングの制限からアクセス出来るVPCがデフォルトVPCのみとなりますので、デフォルトVPCへアタッチしましょう。

エンドポイントの登録後、サービス側で承認する必要があります。
エンドポイントのサービスからエンドポイント接続リクエストを承認しましょう。

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

ここまでで作成されたENIはこのような感じになっています。
独自VPCにRDSとNLBのインターフェースが存在しています。(10.0.xxx.xxx)

そしてデフォルトVPCにVPCエンドポイントのインターフェースが存在しています。(172.31.xxx.xxx)

ターゲットグループがIPアドレスターゲットの場合は、接続元IPアドレスはNLBのプライベートIPアドレスになる仕様です。
なので、RDSのセキュリティグループではNLBのIPアドレスからの接続を許可します。

VPCエンドポイントのセキュリティグループは、LightsailインスタンスのプライベートIPアドレスからの接続を許可します。

接続

これで準備は完了しました。Lightsailから接続してみましょう。
接続ホストはVPCエンドポイントです。

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
       ___ _ _                   _
      | _ |_) |_ _ _  __ _ _ __ (_)
      | _ \ |  _| ' \/ _` | '  \| |
      |___/_|\__|_|_|\__,_|_|_|_|_|
  
  *** Welcome to the LAMP packaged by Bitnami 7.4.28-14                 ***
  *** Documentation:  https://docs.bitnami.com/aws/infrastructure/lamp/ ***
  ***                 https://docs.bitnami.com/aws/                     ***
  *** Bitnami Forums: https://community.bitnami.com/                    ***
Last login: Sat Apr 30 21:18:59 2022 from 54.240.200.12
bitnami@ip-172-26-0-72:~$ mysql -h 172.31.2.6 -u admin -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 66
Server version: 8.0.28 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

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

MySQL [(none)]>

接続出来ましたね。少し操作してみましょう。

MySQL [(none)]> create database hoge;
Query OK, 1 row affected (0.006 sec)

MySQL [(none)]> use hoge;
Database changed
MySQL [hoge]> create table piyo (id int, name varchar(10), updatetime datetime DEFAULT NULL);
Query OK, 0 rows affected (0.041 sec)

MySQL [hoge]> insert into piyo values (1, 'aaa1', '2021-10-27 9:00:00');
Query OK, 1 row affected (0.006 sec)

MySQL [hoge]> insert into piyo values (2, 'bbb1', '2021-10-27 9:00:00');
Query OK, 1 row affected (0.006 sec)

MySQL [hoge]> insert into piyo values (3, 'ccc1', '2021-10-27 9:00:00');
Query OK, 1 row affected (0.005 sec)

MySQL [hoge]> select * from piyo;
+------+------+---------------------+
| id   | name | updatetime          |
+------+------+---------------------+
|    1 | aaa1 | 2021-10-27 09:00:00 |
|    2 | bbb1 | 2021-10-27 09:00:00 |
|    3 | ccc1 | 2021-10-27 09:00:00 |
+------+------+---------------------+
3 rows in set (0.003 sec)

MySQL [hoge]>

独自VPC内のクライアントからRDSへアクセスしてみましたが、Lightsailからの操作内容が反映されていました。
うまくいきましたね。

さいごに

今回はRDSでしたが、NLBのレイヤーで接続出来るものであれば何にでも応用出来そうです。
エンドポイントやNLBのランニングコストを考えるとどうなんだろうという感じは最初に思いますが、何らかの理由でLightsailのまま別のVPCリソースに接続しなければならない場合に使えそうです。
また、プライベートリンクなのでLightsailから別アカウントのリソースにアクセスさせる場合にも活用出来そうです。

NLBからRDSへIPターゲットで接続する方法については以下の記事も参考にしてください。注意事項も紹介されています。