インフラ

AWS SAM(python)でRDSに接続してみる

こんにちは、ちゃりおです。

LambdaでRDSに接続したいことがありました。
備忘録がてらやり方を書いてみます。

Contents

AWS SAMとは

AWS SAMはAWS CloudFormationテンプレート言語の拡張機能であり、サーバーレスアプリケーションをより高いレベルで定義できます。関数の役割の作成などの一般的なタスクを抽象化し、テンプレートの作成を容易にします。 AWS SAMはAWS CloudFormationによって直接サポートされており、AWS CLIおよびAWS SAM CLIを介した追加機能が含まれています。

引用 Tools for Working With AWS Lambda

AWS SAMを使うとサーバレスアプリケーションを簡単に作れます。

SAM CLI準備

AWS CLIが必要なのでインストールします。

$pip3 install awscli --upgrade --user

AWS CLIインストール

SAM CLIをインストールします。pipで入れると簡単です。

$ pip3 install aws-sam-cli
$ sam --version
Installing the AWS SAM CLI on macOS

SAM CLIの使い方は、こちらを見るとわかりやすいです。
Tutorial: Deploying a Hello World Application

テンプレートの雛形を作ります。ランタイムはpythonを選択してください。

$sam init

SAMのテンプレートを書く

今回は、RDSに接続するのでVPC内部にLambdaを作っています。
そのため、VPCIDとSubnetIDを環境にあわせて変更する必要があります。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 'rds_connect'

Globals:
  Function:
    Timeout: 3
Resources:
  SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: vpc-id #VPC IDを書く
      GroupDescription: db connect function.

  Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
          Action:
          - sts:AssumeRole
      Policies:
      - PolicyName: vpc
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - ec2:CreateNetworkInterface
            - ec2:DescribeNetworkInterfaces
            - ec2:DeleteNetworkInterface
            Resource: '*'
      - PolicyName: cloudwatchlog
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Resource: '*'
  RdsConnectFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: rds_connect/
      Handler: app.handler
      Runtime: python3.7
      Role:
        Fn::GetAtt:
        - Role
        - Arn
      VpcConfig:
        SecurityGroupIds:
        - Ref: SecurityGroup
        SubnetIds:
          # Subnet IDを書く
        - subnet-XXXXXXXXXXXXXXXX
        - subnet-XXXXXXXXXXXXXXXX
      Events:
        RdsConnect:
          Type: Schedule
          Properties:
            Schedule: rate(3 minutes)
            Name: line_message_count
            Description: Example schedule
            Enabled: true

Lamabda関数書く(python)

requirement.txtにPyMySQLを追加する

PyMySQL

Lambda関数書く

RDSに接続してSQLを実行する関数です。

import json
import pymysql.cursors

def handler(event, context):
    connection = pymysql.connect(host='db_host',
                             user='db_user',
                             password='db_password',
                             db='db_name',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)
    try:
        with connection.cursor() as cursor:
            sql = '''
            SELECT * FROM 
            '''
            cursor.execute(sql)
            connection.commit()

            result = cursor.fetchone()
            print(result)

    finally:
        connection.close()

SAM build・deploy

それぞれファイルを用意したら、deployします。
sam cliを使うことで簡単にdepooyできます。

パッケージ化して、deployの準備をするためにbuildを実行します。
.aws-sam/build配下にファイルが作成されます。

$sam build

Cloudformationの変更スタック作成・Lambdaへのファイルのアップロードは下記のコマンドで実行できます。
初回は、guidedをつけてスタックの名前をつけます。
2回目以降のデプロイは、sam deployだけでOKです。

$sam deploy --guided

まとめ

SAMでRDSに接続するLambdaを作ってみました。
今回は1日に1回SQLを実行して結果によっては、通知したいという内容だったのでLambdaでやるのがコスパいいかなと思いやってみました。
KMS使ってDBのパスワード暗号化するとか、場合によってはRDS Proxy使うとか改良の余地はありそうです。

rds aurora比較
RDSとAuroraを比較してみたこんにちは、ちゃりおです。 AWSでRDBを使用する際に、AuroraかRDSかで迷ったことはありませんか。 今回は、選択する際の基...
Privatesubnet rds
[AWS]PrivateサブネットにあるRDSにアクセスする方法こんにちは、ちゃりおです。 SaasのサービスからPrivateサブネットにあるDBに接続したいことがありました。 踏み台サーバのSS...
DMS Aurora 移行
DMSでRDS Mysql5.7をAurora Mysql5.7互換に移行してみるこんにちは、ちゃりおです。 Aurora移行を検証してみました。 Aurora移行の方法としては、RDSでAuroraリードレプリカ...