AWS Lambda から Amazon RDS へのアクセス

2019年7月21日

はじめに

AWS Lambda から Amazon RDS に接続し問い合わせする。

Lambda から RDS へのアクセス

Lambda に設定するロールに AWSLambdaVPCAccessExecutionRole をアタッチしておく。Lambda の VPC は RDS と同じものを設定する。

Node.js によるコードは次のようになる。

const { Client } = require('pg')

exports.handler = async (event, context) => {
    const client = new Client({
        user: 'mydbuser',
        host: 'mydbinstance.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com',
        database: 'mydbuser',
        password: 'xxxxxxxx',
        port: 5432,
    });

    await client.connect();

    let rows;

    await client.query("select * from sample where keyword like '%aaa%'")
    .then(res => {
        rows = res.rows;
        client.end();
    })
    .catch(e => {
        console.error(e.stack);
        client.end();
    });

    context.succeed(rows);
};

モジュールのセットアップ

(2021.10.1 追記)

pg モジュールは別途用意する必要がある。たとえば、CloudShell で次のようにする。適当にプロジェクトを作り、pg をインストールする。

$ mkdir postgresql
$ cd postgresql
$ npm init
$ npm install --save pg

zip 圧縮して、S3 にコピーする。

$ zip -r9 postgresql.zip .
$ aws s3 ls
(バケットの確認)
$ aws s3 cp postgresql.zip s3://(バケット名)/postgresql.zip

Lambda で S3 の zip ファイルを読み込んで使えばよい。

VPC Lambda のコールドスタート

VPC 内にある Lambda 関数を呼び出すとき、少し時間がかかることがある。これは「コールドスタート」(cold start) として知られている。Lambda 関数を実行する際に必要なリソースがない時、それを準備するのに時間がかかる。具体的には ENI (Elastic Network Interface) を作成するのに十数秒の時間が必要である。ENI があるかどうかは EC2 のネットワークインターフェイスの設定を見ればわかる。一度 Lambda 関数を実行すると、しばらく ( 数十分?) は ENI が生きているため、その間は関数呼び出しは素早く行われる (warm start)。

VPC Lambda のコールドスタートを避けるためには、つねに Lambda を起こしておけばよい。その方法の一つとして、CloudWatch による定期実行がある。手順は以下の通り。

  • CloudWatch の [イベント]-[ルール] の [ルールの作成] をクリック。
  • "スケジュール" を選び、"一定の速度" で時間間隔を設定。
  • [ターゲットの追加] で呼び出す Lambda 関数を指定。[設定の詳細] をクリック。
  • "名前" と "説明" を入力して [ルールの作成] をクリック。