LoginSignup
7
1

More than 1 year has passed since last update.

Lambda - RDS Proxy(TLSあり) - Auroraの構成でRDS(Aurora)に接続する

Last updated at Posted at 2022-08-18

はじめに

Lambda→RDS Proxy→RDSの接続をやってみたのでその備忘録を残す。

全体の構成イメージは以下。
image.png

※料金について、Auroraはインスタンスの起動時間で料金が発生するので特に注意。Auroraではなく、MySQLとかにすれば無料枠があるのでそちらの方がいいかもしれない。

Auoraのインスタンスを作成

以下の箇所以外はデフォルトのまま設定。

設定項目 画像
テンプレート image.png
インスタンスの設定 image.png

※RDS(Aurora)のインスタンスを作成するために、また、RDS Proxyの設定のための前提条件(Setting up network prerequisites)として、VPCが必要だがこれはデフォルトのものを利用した。

Using RDS Proxy requires you to have a common virtual private cloud (VPC) between your Aurora DB cluster or RDS DB instance and RDS Proxy. This VPC should have a minimum of two subnets that are in different Availability Zones.(RDS Proxyを使用するには、Aurora DBクラスタまたはRDS DBインスタンスとRDS Proxyの間に共通の仮想プライベートクラウド(VPC)を用意する必要があります。このVPCは、異なるAvailability Zoneにある最低2つのサブネットを持っている必要があります。)

Secrets Managerで認証情報を作成

AWS Secrets Manager でのデータベース認証情報の設定を参考に、Secrets Managerにユーザー名とパスワードの認証情報のセットを保存する。これはRDS ProxyがRDSにアクセスする際の認証情報になる。

ステップ 画像
シークレットのタイプを選択 image.png
シークレットを設定 image.png

上記の設定で暗号化キーはデフォルトにしているが、これを自分で生成したものにするとキー1つにつき1$/月かかるっぽいので注意。また、ローテーションの設定は今回はしない設定にした。

一応シークレットに正しい情報を格納できている事を確認してみると、以下のようにちゃんとRDS用のシークレットが作成できている事が確認できる(今回はRDS Proxyを使った接続のためだけに作ったので、パスワードはマスクしてない)。

[study@localhost .aws]$ aws secretsmanager get-secret-value --secret-id dev/db/mysql
{
    "ARN": "arn:aws:secretsmanager:ap-northeast-1:**********:secret:dev/db/mysql-azibNI",
    "Name": "dev/db/mysql",
    "VersionId": "07181751-2208-4048-aa6a-36616c123fd1",
    "SecretString": "{\"username\":\"admin\",\"password\":\"testpassword\",\"engine\":\"mysql\",\"host\":\"database-1.cluster-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com\",\"port\":3306,\"dbClusterIdentifier\":\"database-1\"}",
    ...
}

※RDSへの接続時の認証方式としてはパスワード認証・IAM認証などあるが、RDS Proxyを利用する場合のIAM認証は、RDS ProxyがSecrets Managerから認証情報を取り出す際に使用される(詳細はConnecting to a proxy using IAM authenticationに書かれている通り)。

The IAM authentication applies to RDS Proxy retrieving the user name and password credentials from Secrets Manager. The connection from RDS Proxy to the underlying database doesn't go through IAM.(IAM認証は、RDS ProxyがSecrets Managerからユーザー名とパスワードの資格情報を取得する際に適用されます。RDS Proxyから基礎となるデータベースへの接続は、IAMを経由しません。)

IAMロールを作成する

Setting up AWS Identity and Access Management (IAM) policiesに沿って、RDS ProxyがSecrets Managerにアクセスし、RDSへ接続するのための認証情報を取り出せるようにする設定を行う。

まずは以下の設定でIAMポリシーを作成する。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": [
                "arn:aws:secretsmanager:ap-northeast-1:************:secret:dev/db/mysql-azibNI"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "kms:Decrypt",
            "Resource": "arn:aws:kms:ap-northeast-1:************:key/5b01b7c4-7556-496c-be8c-c30bf1676c7f",
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": "secretsmanager.ap-northeast-1.amazonaws.com"
                }
            }
        }
    ]
}

kms:Decryptについてはシークレットの復号を行う事なので、同じSecrets Managerからの呼び出しのみを許可する設定になっている(より制限をする場合、Conditionの設定が望ましい)。あとは、このポリシーをアタッチできるサービスを設定する(信頼

ちなみに、各ARNが分からなければそれは各ページを見に行けば分かる。

1 2
Secrets Manager image.png
KMS image.png

※マネジメントコンソールではなく、AWS CLIからでも以下のように確認できるだろう。

[study@localhost .aws]$ aws secretsmanager list-secrets
{
    "SecretList": [
        {
            "ARN": "arn:aws:secretsmanager:ap-northeast-1:************:secret:dev/db/mysql-azibNI",
            "Name": "dev/db/mysql",
            "Description": "for RDS Proxy test",
            ...
        }
    ]
}

[study@localhost .aws]$ aws kms list-aliases
{
    "Aliases": [
        ...
        {
            "AliasName": "alias/aws/secretsmanager",
            "AliasArn": "arn:aws:kms:ap-northeast-1:************:alias/aws/secretsmanager",
            "TargetKeyId": "5b01b7c4-7556-496c-be8c-c30bf1676c7f",
            ...
        },
        ...
    ]
}
[study@localhost .aws]$ aws kms list-keys
{
    "Keys": [
        ...
        {
            "KeyId": "5b01b7c4-7556-496c-be8c-c30bf1676c7f",
            "KeyArn": "arn:aws:kms:ap-northeast-1:************:key/5b01b7c4-7556-496c-be8c-c30bf1676c7f"
        }
    ]
}

IAMポリシーが作成できたら、今度はそのポリシーを適用したIAMロールを作成する。IAMロール作成時には信頼されたエンティティを選択というのがあるが、これについてはIAMロールと信頼されたエンティティの関係性を参照ください。設定内容は以下の通り(「信頼されたエンティティを選択」は「カスタム信頼ポリシー」にJSONを書けるのでJSONを書くのが楽)。

ステップ 画像
信頼されたエンティティを選択 image.png
許可を追加 image.png

RDS Proxy の作成

Creating an RDS Proxyに沿って作成していく。

ステップ 画像
ナビゲーションペインのプロキシ image.png
プロキシ設定 image.png
ターゲットグループの設定 image.png
接続 image.png

接続の項目はそれぞれ、

  • シークレット
    Secrets Managerで認証情報を作成の際に作成したシークレットを設定
    これを使ってRDS(Aurora)に認証する
  • IAM ロール
    IAMロールを作成するで作成したIAMロールを設定
    Secrets Managerのシークレットを復号化して実際にRDS(Aurora)に接続する際の認証情報を利用できるようにする
  • IAM 認証
    今回はパスワード認証で認証するのでここはデフォルトのまま許可しないにする

のように設定する。

1点注意として、このRDS Proxyは有効になるまで20分程度かかるようで、作成後すぐに使えない。
image.png

ちなみに、AWS CLIでRDS Proxyの状態確認でき、TargetHealthStateAVAILABLEであれば問題なく作成できていると判断できる。

[study@localhost .aws]$ aws rds describe-db-proxy-targets --db-proxy-name aurora-proxy
{
    "Targets": [
        {
            "Endpoint": "database-1-instance-1.cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com",
            "TrackedClusterId": "database-1",
            "RdsResourceId": "database-1-instance-1",
            "Port": 3306,
            "Type": "RDS_INSTANCE",
            "Role": "READ_WRITE",
            "TargetHealth": {
                "State": "AVAILABLE"
            }
        },
        {
            "RdsResourceId": "database-1",
            "Port": 3306,
            "Type": "TRACKED_CLUSTER"
        }
    ]
}

※上記のEndpointはRDS(Aurora)のエンドポイントであり、RDS Proxyのエンドポイントではないので注意。
image.png

RDS ProxyのエンドポイントはRDS Proxyの設定確認画面から確認できる。
image.png

AWS CLIだと以下。

[study@localhost .aws]$ aws rds describe-db-proxy-endpoints --db-proxy-name aurora-proxy
{
    "DBProxyEndpoints": [
        {
            "DBProxyEndpointName": "default",
            "DBProxyName": "aurora-proxy",
            "Status": "available",
            ...
            "Endpoint": "aurora-proxy.proxy-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com",
            ...
            "TargetRole": "READ_WRITE",
            "IsDefault": true
        },
        {
            "DBProxyEndpointName": "aurora-proxy-read-only",
            ...
            "DBProxyName": "aurora-proxy",
            "Status": "available",
            ...
            "Endpoint": "aurora-proxy-read-only.endpoint.proxy-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com",
            ...
            "TargetRole": "READ_ONLY",
            "IsDefault": false
        }
    ]
}

ひとまずEC2からRDS(Aurora)に接続してみる

VPC内からでないと接続できないので、最も楽そうなEC2を踏み台にしてRDS(Aurora)に接続してみる。また、RDS Proxy経由でもRDS(Aurora)に接続できるか?を検証してみる。

接続の経路としては以下のようなイメージになる(今回はAWSアカウントを作成した際に自動的に作成されるサブネットを利用するので、パブリックサブネットにRDS(Aurora)も属させるような形式になるが、本来はプライベートサブネットとパブリックサブネットに分けるべきだろう。また、EC2は同じサブネットに属していても、セキュリティグループがRDS(Aurora)と別だと、以下で取り上げる【事前準備③】RDSのセキュリティグループにEC2のプライベートIPを追加するのような追加設定が必要になる)。
image.png

※今回のRDS(Aurora)のインスタンスは以下のように、パブリックアクセス可能を「なし」しているため(パブリックアクセス可能にしているのであれば、MySQL Workbench からの接続などで簡単に接続できるだろう)。
image.png

【事前準備①】EC2のインスタンスを作成し、SSHでEC2にローカルから接続する

特にEC2のインスタンス作成については詳細を書かないが、作成した後は以下のようにして接続できる(今回、ローカルマシンはWindows10上に構築しているVirutalBoxのCentOS7.9で、そこからEC2に接続している。WindowsにVirtualBoxでLinux環境を作成する方法はWindows上にLinux(CentOS)のWebアプリ開発環境をvirtualboxで構築するを参照。)。1点、Amazon Linux 2のユーザー名はインスタンスを立ち上げた際にデフォルトでec2-userになるので注意。詳細はインスタンスに関する情報を取得するに書かれている。

[study@localhost .ssh]$ ls 
aurora-stool-server-key.pem  authorized_keys  config  github  github.pub  known_hosts
[study@localhost .ssh]$ chmod 400 aurora-stool-server-key.pem 
[study@localhost .ssh]$ ssh -i aurora-stool-server-key.pem ec2-user@ec2-18-183-53-112.ap-northeast-1.compute.amazonaws.com 
Last login: Wed Aug 17 10:30:37 2022 from 133-32-218-61.east.xps.vectant.ne.jp

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
2 package(s) needed for security, out of 10 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-172-31-11-41 ~]$ 

【事前準備②】Amazon Linux 2にMySQLのクライアントをインストール

インスタンスを作成した後はまだMySQLクライアントがインストールされていない状態なのでインストールを行う。

[ec2-user@ip-172-31-11-41 ~]$ mysql --version
-bash: mysql: コマンドが見つかりません

MySQLのクライアントのインストール方法はMySQL データベースエンジンを実行している DB インスタンスへの接続に書かれている通り。

[ec2-user@ip-172-31-11-41 ~]$ sudo yum install mariadb
...

[ec2-user@ip-172-31-11-41 ~]$ mysql --version
mysql  Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (x86_64) using readline 5.1

【事前準備③】RDSのセキュリティグループにEC2のプライベートIPを追加する

MySQLクライアントをインストールした状態でEC2からRDSに接続しようとしても、セキュリティグループの制約で接続できない。

[ec2-user@ip-172-31-11-41 ~]$ mysql -h database-1-instance-1.cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com -P 3306 -u admin -p
Enter password: 

ERROR 2003 (HY000): Can't connect to MySQL server on 'database-1-instance-1.cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com' (110)

というわけでセキュリティグループのインバウンドを変更して、EC2から接続できるようにする。まず、RDS(Aurora)のインスタンス情報を確認すると、セキュリティグループというのがあるのでそれをクリックするとセキュリティグループ一覧が見れる。
image.png

インバウンドルールのタブから、インバウンドのルールを編集をクリックして新しくEC2のプライベートIPからの接続を追加する(MySQLのアクセスしかしないのでタイプをMySQL/Auroraにする)。
image.png
image.png

EC2のプライベートIPは以下のように確認できる。
image.png

実際にEC2からRDS(Aurora)へ接続してみる

上記の事前準備をした後は、いつものようにDBのホスト・ポート・ユーザー名を指定して接続できるようになる(mydbが今回Auroraを立ち上げる時に作成していたデータベース)。

[ec2-user@ip-172-31-11-41 ~]$ mysql -h database-1-instance-1.cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com -P 3306 -u admin -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 24
Server version: 5.7.12 MySQL Community Server (GPL)

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)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

※今回セキュリティグループでプライベートIPを指定したが、EC2が属するセキュリティグループを追加するという方法もとれる。

RDS Proxy経由で接続した際にRead・Writeするためのテーブル・データを事前作成する

以下のSQLを実行して、データベースにテーブルとデータを作成しておく(一度行を作成して削除した関係でIDは3~になっている)。

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(128) DEFAULT NULL,
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `users` (`name`) VALUES ('yamada tarou'), ('山田 太郎');
MySQL [(none)]> USE `mydb`;

MySQL [mydb]> CREATE TABLE `users` (
    ->   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    ->   `name` varchar(128) DEFAULT NULL,
    ->   `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
    ->   `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    ->   PRIMARY KEY (`id`)
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.07 sec)

MySQL [mydb]> INSERT INTO `users` (`name`) VALUES ('yamada tarou'), ('山田 太郎');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

MySQL [mydb]> SELECT * FROM `users`;
+----+---------------+---------------------+---------------------+
| id | name          | created_at          | updated_at          |
+----+---------------+---------------------+---------------------+
|  3 | yamada tarou  | 2022-08-17 08:58:35 | 2022-08-17 08:58:35 |
|  4 | 山田 太郎     | 2022-08-17 08:58:35 | 2022-08-17 08:58:35 |
+----+---------------+---------------------+---------------------+
2 rows in set (0.00 sec)

ちなみに、RDS Proxy経由ではなく、Auroraのインスタンスに直でアクセスしているので、Read/Writeの両方ができている(RDS Proxy経由ではReadOnlyがあるのでそうはいかない、詳細はEC2からRDS Proxy経由でRDS(Aurora)に接続してみるで)。

EC2からRDS Proxy経由でRDS(Aurora)に接続してみる

イメージとしては以下(AZ・サブネットなどは省略している)。
image.png

アクセスエンドポイントが2つあるのでそれぞれで試してみる。エンドポイントはRDS Proxy の作成の章でRDS Proxyを作成した時に確認した以下の2つ。

  1. aurora-proxy.proxy-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com
  2. aurora-proxy-read-only.endpoint.proxy-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com

1点、RDS Proxy経由で接続する場合、RDS Proxyを作成する際にTLSを有効にしたので、その証明書が必要になる。
image.png

そのため以下のようにして証明書をEC2上に落としておく。

[ec2-user@ip-172-31-11-41 ~]$ wget https://www.amazontrust.com/repository/AmazonRootCA1.pem
[ec2-user@ip-172-31-11-41 ~]$ ls
AmazonRootCA1.pem

※RDSのMySQLへ直に接続する時にはSSL を使用した MySQL コマンドラインクライアントからの接続 (暗号化)に書かれている方法(--ssl-ca=global-bundle.pemオプションを追加する)で接続する必要があるが、今回はRDS Proxy経由だったので証明書がAmazonRootCA1.pemと別物になる(MySQL・Auroraへの接続時の証明書自体はSSL/TLS を使用した DB インスタンスへの接続の暗号化のページにあるglobal-bundle.pemがそれ)。RDS Proxyに接続する際にglobal-bundle.pemを指定すると、以下のようにエラーになる。

[ec2-user@ip-172-31-11-41 ~]$ mysql -h aurora-proxy.proxy-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com --ssl-ca=global-bundle.pem -P 3306 -u admin -p
Enter password: 
ERROR 2026 (HY000): SSL connection error: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed

1つ目のエンドポイントへ接続してみる

接続自体はひとまずEC2からRDS(Aurora)に接続してみるの章の最後で取り上げた方法と同じで、エンドポイントだけRDS Proxyのものに変わる。

[ec2-user@ip-172-31-11-41 ~]$ mysql -h aurora-proxy.proxy-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com --ssl-ca=AmazonRootCA1.pem -P 3306 -u admin -p
...

MySQL [(none)]> USE `mydb`;

MySQL [mydb]> SELECT * FROM `users`;
+----+---------------+---------------------+---------------------+
| id | name          | created_at          | updated_at          |
+----+---------------+---------------------+---------------------+
|  3 | yamada tarou  | 2022-08-17 08:58:35 | 2022-08-17 08:58:35 |
|  4 | 山田 太郎     | 2022-08-17 08:58:35 | 2022-08-17 08:58:35 |
+----+---------------+---------------------+---------------------+
2 rows in set (0.00 sec)

MySQL [mydb]> INSERT INTO `users` (`name`) VALUES ('山田 花子');

MySQL [mydb]> SELECT * FROM `users`;
+----+---------------+---------------------+---------------------+
| id | name          | created_at          | updated_at          |
+----+---------------+---------------------+---------------------+
|  3 | yamada tarou  | 2022-08-17 08:58:35 | 2022-08-17 08:58:35 |
|  4 | 山田 太郎     | 2022-08-17 08:58:35 | 2022-08-17 08:58:35 |
|  5 | 山田 花子     | 2022-08-17 10:58:11 | 2022-08-17 10:58:11 |
+----+---------------+---------------------+---------------------+
3 rows in set (0.00 sec)

特にRead/Writeを問題なく実行できる事が確認できる。

Amazon RDS プロキシを使用して、Amazon RDS MySQL DB インスタンスまたは Aurora MySQL DB クラスターに接続する方法を教えてください。では--ssl-mode=REQUIREDというオプションを設定するように書かれていたが、このオプションがあると以下のようなエラーになったが、インストールしたものがmariadbだったからだと思っている。ちなみに、MySQLのリファレンスを見ると、

Use --ssl-mode=REQUIRED instead of --ssl=1 or --enable-ssl.

となっているので、--ssl=1をオプションに付けて実行したらどうなるのか試したところ、問題なく実行できた。が、MySQLとMariaDBは祖先は同じだが今は違う部分もあるのでMariaDBのリファレンスをちゃんと読むのがいいだろう・・・。

[ec2-user@ip-172-31-11-41 ~]$ mysql --version
mysql  Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (x86_64) using readline 5.1

[ec2-user@ip-172-31-11-41 ~]$ mysql -h aurora-proxy.proxy-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com --ssl-mode=REQUIRED --ssl-ca=AmazonRootCA1.pem -P 3306 -u admin -p
mysql: unknown variable 'ssl-mode=REQUIRED'

[ec2-user@ip-172-31-11-41 ~]$ mysql -h aurora-proxy.proxy-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com -u admin -p --ssl=1 --ssl-ca=AmazonRootCA1.pem
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 1941881813
Server version: 5.7.12 MySQL Community Server (GPL)
...

2つ目のエンドポイント(read-only)へ接続してみる

こちらも1つ目のエンドポイントへ接続してみると同じように接続するまでは全く同じ。ただし、INSERT文(Write)はread-onlyのエンドポイントなので実行できない。

[ec2-user@ip-172-31-11-41 ~]$ mysql -h aurora-proxy-read-only.endpoint.proxy-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com --ssl=1 --ssl-ca=AmazonRootCA1.pem -u admin -p
Enter password: 
...

MySQL [(none)]> USE `mydb`;

MySQL [mydb]> SELECT * FROM `users`;
+----+---------------+---------------------+---------------------+
| id | name          | created_at          | updated_at          |
+----+---------------+---------------------+---------------------+
|  3 | yamada tarou  | 2022-08-17 08:58:35 | 2022-08-17 08:58:35 |
|  4 | 山田 太郎     | 2022-08-17 08:58:35 | 2022-08-17 08:58:35 |
|  5 | 山田 花子     | 2022-08-17 10:58:11 | 2022-08-17 10:58:11 |
+----+---------------+---------------------+---------------------+
3 rows in set (0.01 sec)

MySQL [mydb]> INSERT INTO `users` (`name`) VALUES ('田中 太郎');
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement

RDS(Aurora)のリーダーエンドポイント

もしRDSのクラスター・インスタンスを作成する際に、リーダーを作成していなかった場合、以下のようにTarget group doesn't have any associated read-only instancesというエラーが出る。

[ec2-user@ip-172-31-11-41 ~]$ mysql -h aurora-proxy-read-only.endpoint.proxy-cl1btn8tdegb.ap-northeast-1.rds.amazonaws.com --ssl=1 --ssl-ca=AmazonRootCA1.pem -u admin -p
Enter password: 
...

MySQL [(none)]> SHOW DATABASES;
ERROR 9501 (HY000): Target group doesn't have any associated read-only instances

これはRDS(Aurora)にリーダーのエンドポイントがないからで、単にリーダーエンドポイントを追加すればいい(スクショがない部分はデフォルトのまま)。

1 2
アクション image.png
リーダーの追加 image.png

作成が完了すると、もし既にRDS Proxyが存在していれば自動で紐づく(RDS Proxyを作成する際に指定したのがAurora DB クラスター(今回だと以下のスクショのdatabase-1)だったため)。
image.png

Lambdaを作成する

今回は手動で設定する部分がある関係で、serverlessFWなどIaCではなくZipを自分で上げるスタイルでLambdaを作成する。まずはデフォルトの設定でマネージメントコンソールから関数を作成する。

コード全体は以下。

webpackのoutputの設定についてはModule Definition Systemsを参照。

READMEの通りの手順で、Build→Deployを行えばLambdaのコードの部分の設定はOK。

以下では、RDS Proxy経由でRDS(Aurora)に接続するための設定を行っていく。

ランタイム設定の変更

デフォルトのハンドラーはindex.handlerなので、自分の実装に合わせてここを変更する。
image.png

Lambdaのハンドラーはファイル名.関数名になるので、今回だとファイルがルートディレクトリにないので相対パスも含めて書く必要があり、./dist/lambda.handlerになる(詳細はNode.js の AWS Lambda 関数ハンドラーを参照)。

関数を設定すると、ハンドラー設定の値はファイル名とエクスポートしたハンドラーメソッドの名前をドットで区切ったものになります。コンソールのデフォルトと、このガイドの例では、index.handler です。これは、handler ファイルからエクスポートされた index.js メソッドを示します。

環境変数を設定

以下のように環境変数を設定する。これを使ってLambdaは動く。
image.png

※ここまでの状態ではRDS Proxyのエンドポイントにアクセスできない。続きのVPCの設定などをやってやっと接続できるようになる。

VPCの設定

LambdaからRDS Proxyにアクセスするには、LambdaはRDS Proxyと同じVPCに属している必要がある(LambdaにVPCの設定をせずにデータベースプロキシの設定を追加すると以下のようにInfoが表示される)。
image.png

というわけで設定していくが、まずLambdaにはLambdaのVPCがあり、AWSアカウントで作成したVPCとは別物なので、LambdaをアカウントのVPCに接続させるにはIAMが追加で必要になる(以下公式からの引用)。

Lambda 関数は、常に Lambda サービスが所有する VPC 内で実行されます。Lambda はこの VPC にネットワークアクセスとセキュリティルールを適用し、VPC を自動的に維持および監視します。Lambda 関数がアカウント VPC 内のリソースにアクセスする必要がある場合は、VPC にアクセスするための関数を設定します。

必要なIAMは実行ロールとユーザーアクセス許可に書かれている。今回はマネージメントコンソールでLambdaを作成し、その時に特に何も設定しなかったのでデフォルトで新しいLambdaの実行ロールが作成されているので、そこに新しくポリシー(AWSLambdaVPCAccessExecutionRole)をアタッチする。

1 2
Lambdaの実行ロール image.png
IAMロール image.png
ポリシーを rds-proxy-lambda-func-role-jdg11om4 にアタッチ image.png

次にVPCの設定をしていく。RDS ProxyのVPCと同じVPC(AWSアカウントを作成した際にデフォルトで作成されるVPC)になるので、以下のように設定していけばいい。
image.png

※Lambdaの実行ロールについてはLambdaの実行ロール Lambda実行時のAWS_ACCESS_KEY_IDとかは何になる?も参照ください。

データベースプロキシの設定

VPCの設定ができたので、最後にデータベースプロキシの設定もする。これは既に作成済みのRDS Proxyを設定するだけなので以下のように簡単にできる。
image.png

2022-08-23追記

IAM認証ではなく、パスワード認証の場合にはLambdaにデータベースプロキシの設定をする必要はないようである。実際にデータベースプロキシの設定をせずに、RDS Proxyへ経由でAuroraへの接続もできた。

LambdaからRDS Proxy経由でRDS(Aurora)に接続する

後は実際にLambdaを実行するだけ。実行してみると以下のように問題なくデータが取得できている事が確認できた。あとはread-onlyのエンドポイントを使い分けて実装すれば実装として完成になるだろう。
image.png

study@localhost:~/workspace/rds-proxy-lambda (main *)
$ aws lambda invoke --function-name rds-proxy-lambda-func response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
response.json
{
	"statusCode": 200,
	"body": [
		{
			"id": 3,
			"name": "yamada tarou",
			"created_at": "2022-08-17T08:58:35.000Z",
			"updated_at": "2022-08-17T08:58:35.000Z"
		},
		{
			"id": 4,
			"name": "山田 太郎",
			"created_at": "2022-08-17T08:58:35.000Z",
			"updated_at": "2022-08-17T08:58:35.000Z"
		},
		{
			"id": 5,
			"name": "山田 花子",
			"created_at": "2022-08-17T09:47:59.000Z",
			"updated_at": "2022-08-17T09:47:59.000Z"
		}
	]
}

※コードについて1点補足として、EC2からRDS Proxy経由でRDS(Aurora)に接続してみるでEC2から接続する時もそうだったが、今回のRDS ProxyはTLSを有効化しているので証明書が必要になる。そのため、myslqのコネクションを作成する時にSSL optionsAPI and Configurationから飛べるページ)に書かれているようなSSLのための追加実装が必要になっている。

	const connection = await mysql.createConnection({
		host: process.env.HOST,
		port: 3306,
		user: process.env.USER_NAME,
		password: process.env.PASSWORD,
		database: 'mydb',
		ssl: {
			ca: fs.readFileSync(path.join(__dirname, 'AmazonRootCA1.pem'))
		}
	});

まとめとして

TLSの証明書が必要でそれがどこにあるのかわからず少し躓いた部分があったが、公式の説明通りに比較的に簡単に構築できた。

参考文献

おまけ

IAMユーザーで請求情報を見れるようにする

AWS Billing コンソールへのアクセスのアクティブ化https://console.aws.amazon.com/billing/home#/account をクリックし、rootアカウントの設定ページに飛ぶ。

ページの真ん中の方にあるIAM ユーザー/ロールによる請求情報へのアクセスを編集すればOK。
image.png

CICD

S3にzipをアップロードするという古典的な方法だが…。以下のソースがそれ。

7
1
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
7
1