ご挨拶
タイトルの通りLambdaからRDSへ接続してみたので記事を書いていきます。
最近業務でLambdaを使用することが増えてきたので勉強になればと思いやってみました。
やること
LambdaでプライベートサブネットにあるRDS MySQLに向けてSQLを実行して実行結果を確認します。
今回RDSの作成はCloudFormationを使用しています。
事前にプライベートサブネットを二つ作成しています。
以下の手順で進んでいきます。
- Lambda関数の作成
- IAMロールの編集
- RDSの作成
- LambdaをRDSに接続できるように設定
- テスト実行
構成図
参考にしたサイト
チュートリアル: Amazon VPC の Amazon RDS にアクセスする Lambda 関数の設定
pymysqlのドキュメント
やってみる
1. Lambda関数の作成
マネジメントコンソールからLambdaへ移動
移動後、関数→関数の作成をクリック
クリック後上から順に以下の画像のように選択と入力を行います
関数名はお好みで大丈夫です。
今回はPythonを使用して関数を作成するのでランタイムはPython3.9を選択しました。
IAMロールは新しく作成してくれるものを選択することでCloudWatch logsへのアクセス権をいい感じに絞ったものが作成されます。
作成が完了したら一旦マネジメントコンソールでの作業は終わりでコードを作成します。
コード作成
pythonでMySQLの操作をするのにpymysqlというモジュールを使用します。
pymysqlはLambdaのデフォルトでは使用できないのでモジュールをzipにしてアップロードします。
import os
import pymysql
host = os.environ['RDS_HOST_NAME']
user = os.environ['USER']
password = os.environ['PASS']
db = os.environ['DB']
connection = pymysql.connect(host=host, user=user, password=password, database=db)
def lambda_handler(event, context):
with connection.cursor() as cursors:
cursors.execute('show databases')
print(cursors.fetchall())
作成されているスキーマを取得するものを作成しました。
execute()でSQLを実行して結果をfetchall()で取ってきています。
ここまで出来たらファイルを保存します。
保存したディレクトリ(フォルダ)と同じ階層にpymysqlを入れます。
以下のコマンドを実行します。
pip install PyMySQL -t /ファイルがあるディレクトリ
もしくはファイルがあるディレクトリに移動して以下のコマンド実行
pip install PyMySQL -t ./
インストールができたらファイルとモジュールを一つのzipにします。
zipができたらマネジメントコンソールに戻ってアップロードします。
以下の画面からアップロード元→.zipファイル→アップロードの順でクリックして上記手順で作成したzipファイルをアップロードします。
2. IAMロールの編集
上記1まで出来たらIAMロールを編集します。
RDSにアクセスできるようにするにはENIが必要なためIAMでアクセス権を与えます。
以下の画面の設定→アクセス権限→実行ロールのところでLambdaにアタッチされているIAMロールが確認できます。
そこからIAMロールをクリックすると編集ができます。
クリックするとIAMの画面に移動します。
移動したら「ポリシーをアタッチします」をクリックしてIAMポリシーを選択します。
選択するポリシーはAWSLambdaVPCAccessExecutionRoleです。
アタッチできたらIAMの設定は終了です。
3. RDSの作成
RDSの作成は以下のyamlで作成しました。
CloudFormationの使用方法は以下の記事の「CloudFormationでスタック作成」をご覧ください。
【AWS】 CloudFormationで基本的な構成のEC2とRDSを作る
AWSTemplateFormatVersion: "2010-09-09"
Description: create rds
#パラメータ
Parameters:
vpcid:
Type: AWS::EC2::VPC::Id
Description: Enter vpcid
subnetid1:
Type: AWS::EC2::Subnet::Id
Description: Enter RDS subnetid
subnetid2:
Type: AWS::EC2::Subnet::Id
Description: Enter RDS subnetid
rdssubnetgroupname:
Type: String
Description: Enter RDS subnet groupname
rdsdbname:
Type: String
Description: Enter RDS DBname
rdsusername:
Type: String
Description: Enter RDS username
AllowedPattern: '[a-zA-Z0-9]*'
rdspassword:
Type: String
Description: Enter RDS password
MinLength: '8'
MaxLength: '41'
AllowedPattern: '[a-zA-Z0-9]*'
#リソース
Resources:
lambdasecuritygroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: lambda-securitygroup
SecurityGroupEgress:
- IpProtocol: -1
FromPort: -1
ToPort: -1
CidrIp: 0.0.0.0/0
VpcId: !Ref vpcid
rdssecuritygroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: rds-securitygroup
SecurityGroupEgress:
- IpProtocol: -1
FromPort: -1
ToPort: -1
CidrIp: 0.0.0.0/0
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !Ref lambdasecuritygroup
VpcId: !Ref vpcid
rdssubnetgroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: rdssubnetgroup
SubnetIds:
- !Ref subnetid1
- !Ref subnetid2
DBSubnetGroupName: !Ref rdssubnetgroupname
Tags:
- Key: Name
Value: rdssubnetgroup
rdsinstance:
Type: AWS::RDS::DBInstance
Properties:
AllocatedStorage: 20
DBInstanceClass: db.t2.micro
DBSubnetGroupName:
!Ref rdssubnetgroup
DBName: !Ref rdsdbname
Engine: mysql
EngineVersion: "5.7.34"
MasterUsername: !Ref rdsusername
MasterUserPassword: !Ref rdspassword
StorageType: gp2
Tags:
- Key: Name
Value: rdsinstance
VPCSecurityGroups:
- !Ref rdssecuritygroup
上記のテンプレートを使用してプライベートサブネットにRDSを作成します。
4. LambdaをRDSに接続できるように設定
RDSの作成ができたら環境変数を登録していきます。
Lambda関数の設定画面から環境変数→編集をクリック
キーと値には以下の4つを設定します。
キー | 値 |
---|---|
RDS_HOST_NAME | RDSのエンドポイント |
USER | MySQLのユーザ (CloudFormationで作成時に入力したユーザ) |
PASS | MySQLのパスワード (CloudFormationで作成時に入力したパスワード) |
DB | DB名 (CloudFormationで作成時に入力したDB名) |
次にVPCの設定を行います。
Lambdaの設定→VPC→編集をクリック
クリックしたら上からVPC、サブネット、セキュリティグループを選択します。
VPCはRDSと同じVPCを選択します。
サブネットはプライベートサブネットを選択します。
セキュリティグループはCloudFormationで作成したlambda-securitygroupを選択します。
5. テスト実行
上記まで完了したらテスト実行してみます。
コード→Testをクリックします。
テストを実行してFunction Logsに以下のデータベースが出力されれば成功です。
(('information_schema',), ('innodb',), ('lambda_to_rds',), ('mysql',), ('performance_schema',), ('sys',))
感想
information_schemaが見れるので各テーブルのレコード数やAutoIncrementの数値を取ってきてCloudWatchメトリクスに登録するなどの活用ができそうだと思いました。(小並感)
使用方法によってはRDS Proxyというものを使用してLambdaからの大量の接続を維持することも検討する必要があるようです。
AWS LambdaでAmazon RDS Proxyを使用する