Help us understand the problem. What is going on with this article?

VPC内のLambdaを用いたAuroraからの情報取得

More than 3 years have passed since last update.

やりたいこと

ユーザーの登録状況など、日ごとに情報を取得したいことがあります。取得したいデータがVPC内部のPrivate SubnetのAuroraにある場合、従来は内部にインスタンスを立てて取得する必要が以前はありました。しかし、結構前からLambdaをVPC内に立てることが可能になったので、このような要件の場合もLambdaを利用できるようになりました。

今回はVPC内にLambdaを動作させて、RDS内部の情報を定期的に取得するLambda関数を作成します。

想定構成

VPCのPrivate Subnet内部にRDSとLambdaが配置されます。Lambdaは1日に一度動作してAuroraから情報を取得し、S3にCSVファイルとして保存します。

スクリーンショット 2017-07-22 20.21.26.png

必要な設定

RDSから情報を取得するVPC内のLambdaを作成する上でまず、以下の3点については既に用意されていると想定します。

  • Amazzon Aurora
  • VPC、Public Subnet、Private Subnetなどの設定

IAMロールの作成

VPC内でLambdaを動作させるためにAWSLambdaVPCAccessExecutionRoleポリシーが必要となります。このポリシーを含んだIAMロールを作成します。

スクリーンショット 2017-07-22 20.43.10.png

セキュリティグループ

Auroraにはセキュリティグループが設定されていると思います。AuroraにアクセスするためにAuroraに設定されているセキュリティグループのインバウンドにこれから動作させるLambdaのセキュリティグループを追加する必要があります。

Lambda関数の作成

VPC内のLambdaを作成していきます。Lambda関数の作成で"Blank Function"を選択します。
スクリーンショット 2017-07-23 11.21.10.png
トリガーは後でCloudWatchイベントを設定しますので、次へを選択。
スクリーンショット 2017-07-23 11.21.21.png
Lambda関数名を適当に選択してpython2.7を選択します。
スクリーンショット 2017-07-23 11.22.24.png
先ほど作成したIAMロールを選択します。バッチ処理でデータベースからデータを取得してCSVファイルを作成する想定なので、タイムアウト時間を長く設定しておきます。
スクリーンショット 2017-07-23 11.23.14.png
詳細設定でVPCを選択します。Lambdaも通常のインスタンスと同様に可用性の観点からアベイラビリティゾーンそれぞれのプライベートサブネットを選択します。Auroraに接続するために先ほど設定したセキュリティグループを選択します。
スクリーンショット 2017-07-23 11.24.19.png

Lambda関数の実装

事前準備

pymysqlというライブラリを利用しますので、working directoryを作成してそこにpymysqlをインストールしておきます。

$ pip install pymysql -t .
DistutilsOptionError: must supply either home or prefix/exec-prefix -- not both

しかし上記のようなエラーが発生します。これはMacの環境でbrewを使ってPythonをインストールしている場合に起こる問題で、ホームディレクトリに.pydistutils.cfgという名前のファイルを作成し以下を記述すれば問題は解決されます。

[install]
prefix=

コード

app.pyには以下のようなコードを記述します。MySQLとの接続は、パフォーマンスの観点からlambda_handler関数外で行います。

import sys
import logging
import pymysql

RDS_HOST="XXXX"
NAME="XXXX"
PASSWORD="XXXX"
DB_NAME="XXXX"

logger = logging.getLogger()
logger.setLevel(logging.INFO)

try:
    conn = pymysql.connect(RDS_HOST, user=NAME, passwd=PASSWORD, db=DB_NAME, connect_timeout=5)
except:
    logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
    sys.exit()

def lambda_handler(event, context):
    results = []
    with conn.cursor() as cur:
        cur.execute('select * from tablename')
        for row in cur:
            results.append(row)
    return results

コードのデプロイ

zipファイルに固めてAWSコンソールを利用してアップロードします。

$ zip -r upload.zip *

CloudWatchイベント

24時間に1度データを集計するためにLambdaを起動するためのCloudWatchイベントを事前に作成する必要があります。毎日0時(UTC: 日本時間午前9時)にデータを取得するように設定します。

Link

http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/vpc-rds.html

yokobonbon
時々興味のままにコードいじってます。自分のメモ代わりにQiita使ってます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away