調べ物した結果

現役SEが仕事と直線関係ないことを調べた結果を。

lambda->AWS RDS Proxyにうまく接続できなかった(そのうちリベンジする)


目次

※掲題の件、達成できなかったのでその手の情報が欲しくてたどり着いてかたすみません。※

リングフィットアドベンチャーの力で子供二人(2歳、4歳)を同時に抱きかかえても平気になってきました。
お腹周りは一向に痩せません。痩せろ。
勉強がてらにRDS Proxy なるものを使ってみようとやってみたけど、どうにもうまくできないので一回敗北宣言。
というのが今回の内容。

環境とか

・リージョン:東京
・作業環境 :マネージドコンソール

何がうれしくなるためにRDS Proxyを使うのか。

lambdaからのRDS接続用。ということで間違いないのかな。と思っています。
RDSはMySQLだとか、OracleなんかのRDBMSを使うことのできるサービスです。
lambdaはサーバレスアーキテクチャを構成するうえで、欠かすことのできないコアなサービスだと思いますが、
lambdaからのRDS(というよりリレーショナルデータベース)へのアクセスは「同時接続数」の問題で基本的にはアンチパターンとされていました。
と、いうのも例えばlambdaでRDSに対してなんらかのクエリを発行するように組み込んでいた場合、
lambdaは状況に応じて自動的にスケーリングし、10なり100なり。それ以上同時にクエリ発行=接続数ということがありえてしまいます。
一方RDS(RDBMS)はそのような大量の同時接続数に対してサポートしていることは稀です。(できないことはないでしょうが・・・)
オンプレ環境の開発であれば、コネクションプールなどの仕組みを組み込んでこの辺りをうまいことやりくりしたりするんですが、
lambdaで構築するのも骨がおれる作業かと思います。(やって見たことがないのでなんともです。)
ということでlambdaでRDS(RDBMS)接続。はアンチパターンとなっていました。
このあたりはblackbeltのyoutube動画見てみるとよいかと思います。

とりあえずやってみたらええねや。

ここを参考にしながら実際にやっていきます。
aws.amazon.com

とりあえず接続用のRDSをたてる。

RDSコンソールでRDSを建てちゃいましょう。現行(2020/3/21時点)でRDS Proxyはプレビュー版で、全部のRDBMSに対応しているわけではないです。
今回はMySQLを使用します。説明は画像ペタペタ作戦でいきます。
でーたべーす~
gyazo.com
設定~
gyazo.com
初期のデータベース名。接続確認でつかうのでお忘れなく設定!
gyazo.com
ほかはデフォルトのままなので割愛しますが、パブリックアクセスはオフでやります。
gyazo.com

AWS SeacretManagerにアクセスできるIAMポリシーを作成する。

AWS SeacretManagerにシークレットを作成する

といっても初めて使うサービスなのでだいぶわからない状態ではありますが。
ユーザー名はRDSのほうと合わせました。
gyazo.com
シークレット名はわかりやすく「proxy-sample-secret」としました。
gyazo.com
あとはデフォルトでよいよいなのでそのままポチポチ。で出来上がります。
gyazo.com
詳細確認してARNをどこかにメモしておきましょう。後ほど使います。
gyazo.com

シークレットを読み取れるポリシーを作る

IAMコンソールから新規のポリシーを作ります。
JSONベタバリでARNを読み替えてもよさそうですし、ビジュアルエディタでポチポチでもよいと思います。
私はJSONベタバリしました。
gyazo.com
ポリシーの名前はわかりやすいもので、好きなものでよいでしょう。
gyazo.com

シークレットを読み取れるIAMロールを作る

IAMコンソールから新規のロールを作成します。
gyazo.com
作成ボタンをぽちっとやって、作成していきます。
RDS用のロールなので、RDSを選びます。
gyazo.com
JSONは手順に従うので「Add Role to Database」でよいのではないでしょうか。
gyazo.com
ポリシーは先ほど作成したものを使用します。このタイミングで作成しても問題ないでしょう。
gyazo.com
ロール名もポリシーと同じで、いい感じな名前でOKです。
gyazo.com

ロールに信頼ポリシー(?)を確認する

おそらく「信頼関係」のことだと思われる。
先ほど作成したポリシーを選択して、信頼関係タブを選択します。
gyazo.com
信頼関係の編集を確認して、以下のようになっていることを確認します。
※編集が必要かとおもいましたが、初めから編集済みのようでした。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "rds.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

RDSProxyとlambdaを関連付ける

とりあえず新規に関数を作成

gyazo.com
sampleがNode.jsなのでとりあえずコピペで行けるようにつかったことないけどNode.jsにした。

RDS Proxyを作る

先につくった関数の最下部にプレビューでデータベースプロキシ。の設定がある。ここから作っていく。
gyazo.com
すでに前準備はすましているので、適当な項目を選択するのに説明はいらないと思う。
それぞれ、これまで作ってきたRoleだったり、シークレットのARNだったりを設定する。
gyazo.com

プロキシへの接続情報の環境変数を作る。

本当はIAM認証がよいらしい。サンプルでは説明の簡易さを優先してSecrets Managerの認証情報を利用しているので、
合わせます。とのこと。
なので私も合わせます。ひとまずRDSへのアクセス用の文字列をLambda環境変数に放り込んでいきます。

endpoint

RDSのエンドポイントはRDSコンソール->Proxiesから確認できる。
gyazo.com

user

データベースのユーザ名。とりあえず管理者でいいと思う。

password

パスワード。管理者のパスワード

dbname

データベーススキーマ名。設定で間違えていなけれ、sample_dbという名前で作成されているはず。
わからなくなったらRDSコンソールの設定タブで確認できるので、確認しよう。

ここまでは順調に来たのだけれど。

Node.jsのMysql周りの環境はcloud9を使うと簡単にlambdaにデプロイできてらくちんだった。
ところが、いざ接続テストをしてみるとつながらない。 ETIMEOUT, ETIMEOUT, ETIMEあうとぉぉぉぉ。
で一向にクエリの結果が返ってこない。

経験的に、タイムアウトの発生は権限周りのことがおおいので、もう一回改めてチャレンジしてみようと思う。

君にはこれが・・・

・lambda -> RDS のそもそもの知識が足りない
・secret manager への理解が足りない。
・Node.js は初めて使ったけどたぶん使い方はあってる。

というのが現状と思われる。無理に外からの接続もOFFにしてMySQL建てちゃったけど、
次は外部からもつなぎながらどこが悪いのか検証していく予定。

あとは、なんかロールつくったり、プロキシを先にたてとかなくてもlambdaからぽちぽち適当にやっていくと諸所の設定をやってくれるみたいなので、それと今回のとで何が違うのか比較するつもり。だ。
ということで次。がんばる。次。