はじめに
AWS LambdaがVPCに対応したので、プライベートネットワーク上のRDSにアクセスできるようになりました。
Pythonでやってみましたので、手順をメモしておきます。
Python LambdaからRDSへの接続はMySQL-pythonを利用します。
外部ライブラリを利用する場合は、スクリプトとライブラリを合わせてzip圧縮し、アップロードする必要があります。
今回はEC2(Amazon Linux AMI 2016.03.0)で準備したときの手順です。
準備
テスト用RDSを用意します。
ここと同じ手順で、RDS(MySQL)の起動とテーブルの作成を行います。
作業ディレクトリを作成
$ mkdir lambda-rds
$ cd lambda-rds/
pipをアップグレード
$ sudo pip install --upgrade pip
必要なパッケージをインストール
$ sudo yum -y install mysql mysql-devel gcc
MySQL-pythonをカレントディレクトリ内にインストール
そのままインストールしようとすると下記のようなエラーが出るので、
Exception:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/pip/basecommand.py", line 209, in main
status = self.run(options, args)
File "/usr/local/lib/python2.7/site-packages/pip/commands/install.py", line 357, in run
for item in os.listdir(lib_dir):
OSError: [Errno 2] そのようなファイルやディレクトリはありません: '/tmp/tmpxhz25M/lib/python'
ディレクトリ内に下記のファイルを作成します。
[install]
install-purelib=$base/lib64/python
インストールを実行します。
pipをアップグレードするとpipのパスが/usr/binから/usr/local/binに代わるみたいなので、フルパスで実行しています。
$ /usr/local/bin/pip install MySQL-python -t .
$ ls
MySQL_python-1.2.5.egg-info
MySQLdb
_mysql.so
_mysql_exceptions.py
_mysql_exceptions.pyc
setup.cfg
スクリプトの作成
ファイル名はlambda_function.py、ファンクション名はlambda_handlerにします。
import MySQLdb
def lambda_handler(event, context):
connect = MySQLdb.connect(host='lambda.xxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com', db="lambda", user="lambda", passwd="XXXXXXXX")
connect.cursorclass = MySQLdb.cursors.DictCursor
cursor = connect.cursor()
cursor.execute('SELECT * FROM sample')
row = cursor.fetchone()
cursor.close()
connect.close()
return row
Shared Object Fileのコピー
libmysqlclient.so.18をカレントディレクトリにコピーします。
$ cp /usr/lib64/mysql/libmysqlclient.so.18 .
これがないとlambda実行時に、
Unable to import module 'lambda_function': libmysqlclient.so.18: cannot open shared object file: No such file or directory
というエラーになります。
カレントディレクトリすべてをzip圧縮
$ zip -r upload.zip *
AWSマネージメントコンソールからLambda Functionの作成
Select blueprint → Skip
-
Configure function
- Name: 適当
- Description: 適当
- Runtime: Python 2.7
-
Lambda function code
- Code entry type: Upload a .ZIP file をチェックし、upload.zipをアップロード
-
Lambda function handler and role
- Handler: lambda_function.lambda_handler (ファイル名.関数名)
- Role: Basic with VPC を選択
- Role Nameを編集し、Allowを選択
-
Advanced settings
- VPC: RDSのVPCを選択
- Subnets: デフォルト(全選択) サブネットを固定する場合は、選択
- Security Groups: RDSにアクセスできるセキュリティグループを選択
動作確認
Input test eventはそのままで、Test
こんな感じで返ってきました。
{
"id": 1,
"value": "test"
}