AWS Lambda 関数から VPC 内の RDS を利用するための設定
[履歴] [最終更新] (2017/10/14 15:10:57)

概要

Lambda 関数が VPC 内のリソースにアクセスするためには create-function 時に --vpc-config でサブネットに所属させる必要があります。リソースの具体例として RDS にアクセスするために必要な設定方法をまとめます。

RDS の構築

AmazonRDSFullAccess が付与された IAM を用いて以下の create-db-instance コマンドで RDS インスタンスを作成します。

aws rds create-db-instance \
--profile lambda-test-user-20170929 \
--region ap-northeast-1 \
--db-instance-identifier mydbinstance \
--db-instance-class db.t2.micro \
--engine mysql \
--engine-version 5.7.17 \
--allocated-storage 5 \
--no-publicly-accessible \
--db-name mydb \
--master-username mymasteruser \
--master-user-password mymasteruser \
--backup-retention-period 3

IAM ロールの作成

こちらのページと同様に Lambda 関数が必要とする権限が付与された IAM ロールを作成します。

  • ロール名 my-lambda-rds-role
  • AWS service role Lambda
  • ポリシー AWSLambdaVPCAccessExecutionRole

Lambda 関数の登録

ここでは Node.js を利用します。MySQL クライアントとしては mysqljs/mysql を利用します。

npm install mysql

RdsSample.js

// 依存ライブラリ
var mysql = require('mysql');
var connection = mysql.createConnection({
  host: 'mydbinstance.cncechgxndis.ap-northeast-1.rds.amazonaws.com',
  user: 'mymasteruser',
  password: 'mymasteruser',
  database: 'mydb'
});

// Lambda 関数が実行される度に処理される内容です。
exports.handler = function(event, context, callback) {

  // コネクションを確立します。
  connection.connect(function(err) {
    if (err) {
      console.error('error connecting: ' + err.stack);
      return;
    }
    console.log('connected as id ' + connection.threadId);
  });

  // テーブルを作成します。
  connection.query('CREATE TABLE IF NOT EXISTS my_table (cola VARCHAR(32) PRIMARY KEY, colb INT)', function (error) {
    if (error) throw error;
    console.log('created my_table');
  });

  // レコードを削除します。
  connection.query('DELETE FROM my_table', function (error, results, fields) {
    if (error) throw error;
    console.log('deleted ' + results.affectedRows + ' rows');
  });

  // レコードを挿入します。
  connection.query('INSERT INTO my_table VALUES ?', [
    [['aaa', 123], ['bbb', 987]]
  ], function (error, results, fields) {
    if (error) throw error;
    console.log('inserted ' + results.affectedRows + ' rows');
  });

  // レコードを検索します。
  connection.query('SELECT ?? FROM ?? WHERE cola = ?', [
    ['cola', 'colb'], // `??` によって ' ではなく ` で囲います。
    'my_table', // `??` によって ' ではなく ` で囲います。
    'bbb'
  ], function (error, results, fields) {
    if (error) throw error;
    console.log(JSON.stringify(results));
  });

  // コネクションを切断します。
  connection.end();

  // Lambda 関数の呼出しもとに結果を返します。
  callback(null, "message");
};

zip 化します。

zip -r RdsSample.zip RdsSample.js node_modules/

create-function コマンドで AWS にアップロードします。--vpc-config で RDS と同じサブネットを指定します。古いバージョンの aws コマンドでは --vpc-config を利用できないことがあります。

aws lambda create-function \
--profile lambda-test-user-20170929 \
--region ap-northeast-1 \
--function-name RdsSample \
--zip-file fileb://RdsSample.zip \
--role arn:aws:iam::123412341234:role/my-lambda-rds-role \
--handler RdsSample.handler \
--runtime nodejs6.10 \
--vpc-config SubnetIds=subnet-xxxxxxxx,subnet-yyyyyyyy,SecurityGroupIds=sg-zzzzzzzz

動作検証

invoke コマンドで実行して CloudWatch ログが想定通りに出力されることを確認します。

aws lambda invoke \
--profile lambda-test-user-20170929 \
--region ap-northeast-1 \
--invocation-type RequestResponse \
--function-name RdsSample \
output.txt
関連ページ
    概要 AWS Lambda はイベントドリブンな「関数」を登録できるサービスです。例えば S3 に画像がアップロードされたときにサムネイル用のサイズに加工する処理が記述された関数を登録できます。基本的な使い方をまとめます。 事前準備 関数の登録はブラウザで AWS コンソールにログインして行うこともできますが、本ページでは