18
10

More than 1 year has passed since last update.

LambdaからRDSへ接続してみる

Posted at

ご挨拶

タイトルの通りLambdaからRDSへ接続してみたので記事を書いていきます。
最近業務でLambdaを使用することが増えてきたので勉強になればと思いやってみました。

やること

LambdaでプライベートサブネットにあるRDS MySQLに向けてSQLを実行して実行結果を確認します。
今回RDSの作成はCloudFormationを使用しています。
事前にプライベートサブネットを二つ作成しています。
以下の手順で進んでいきます。

  1. Lambda関数の作成
  2. IAMロールの編集
  3. RDSの作成
  4. LambdaをRDSに接続できるように設定
  5. テスト実行

構成図

image.png

参考にしたサイト

チュートリアル: Amazon VPC の Amazon RDS にアクセスする Lambda 関数の設定
pymysqlのドキュメント

やってみる

1. Lambda関数の作成

マネジメントコンソールからLambdaへ移動
スクリーンショット 2021-10-30 182647.png
移動後、関数→関数の作成をクリック
スクリーンショット 2021-10-30 183025.png
クリック後上から順に以下の画像のように選択と入力を行います
関数名はお好みで大丈夫です。
今回はPythonを使用して関数を作成するのでランタイムはPython3.9を選択しました。
IAMロールは新しく作成してくれるものを選択することでCloudWatch logsへのアクセス権をいい感じに絞ったものが作成されます。
image.png
作成が完了したら一旦マネジメントコンソールでの作業は終わりでコードを作成します。

コード作成

pythonでMySQLの操作をするのにpymysqlというモジュールを使用します。
pymysqlはLambdaのデフォルトでは使用できないのでモジュールをzipにしてアップロードします。

lambda_function.py
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を入れます。
以下のコマンドを実行します。

powershell
pip install PyMySQL -t /ファイルがあるディレクトリ

もしくはファイルがあるディレクトリに移動して以下のコマンド実行

pip install PyMySQL -t ./

インストールができたらファイルとモジュールを一つのzipにします。
zipができたらマネジメントコンソールに戻ってアップロードします。
以下の画面からアップロード元→.zipファイル→アップロードの順でクリックして上記手順で作成したzipファイルをアップロードします。
スクリーンショット 2021-10-30 233442.png

2. IAMロールの編集

上記1まで出来たらIAMロールを編集します。
RDSにアクセスできるようにするにはENIが必要なためIAMでアクセス権を与えます。
以下の画面の設定→アクセス権限→実行ロールのところでLambdaにアタッチされているIAMロールが確認できます。
そこからIAMロールをクリックすると編集ができます。
スクリーンショット 2021-10-30 234510.png
クリックするとIAMの画面に移動します。
移動したら「ポリシーをアタッチします」をクリックしてIAMポリシーを選択します。
選択するポリシーはAWSLambdaVPCAccessExecutionRoleです。
アタッチできたらIAMの設定は終了です。

3. RDSの作成

RDSの作成は以下のyamlで作成しました。
CloudFormationの使用方法は以下の記事の「CloudFormationでスタック作成」をご覧ください。
【AWS】 CloudFormationで基本的な構成のEC2とRDSを作る

create_rds.yml
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関数の設定画面から環境変数→編集をクリック
スクリーンショット 2021-10-31 000648.png
キーと値には以下の4つを設定します。

キー
RDS_HOST_NAME RDSのエンドポイント
USER MySQLのユーザ (CloudFormationで作成時に入力したユーザ)
PASS MySQLのパスワード (CloudFormationで作成時に入力したパスワード)
DB DB名 (CloudFormationで作成時に入力したDB名)

次にVPCの設定を行います。
Lambdaの設定→VPC→編集をクリック
スクリーンショット 2021-10-31 003018.png
クリックしたら上からVPC、サブネット、セキュリティグループを選択します。
VPCはRDSと同じVPCを選択します。
サブネットはプライベートサブネットを選択します。
セキュリティグループはCloudFormationで作成したlambda-securitygroupを選択します。

5. テスト実行

上記まで完了したらテスト実行してみます。
コード→Testをクリックします。
スクリーンショット 2021-10-31 004712.png
テストを実行してFunction Logsに以下のデータベースが出力されれば成功です。

データベース
(('information_schema',), ('innodb',), ('lambda_to_rds',), ('mysql',), ('performance_schema',), ('sys',))

感想

information_schemaが見れるので各テーブルのレコード数やAutoIncrementの数値を取ってきてCloudWatchメトリクスに登録するなどの活用ができそうだと思いました。(小並感)
使用方法によってはRDS Proxyというものを使用してLambdaからの大量の接続を維持することも検討する必要があるようです。
AWS LambdaでAmazon RDS Proxyを使用する

18
10
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
18
10