AWS LambdaからRDS(MySQL)にSQLを発行する
RDS(MySQL)はVPCのパブリックサブネットに配置されている前提とします。
LambdaからRDSにアクセスするには同一VPC上にLambdaを置く必要があるかもしれません。
2018/04/22 追記 「AWSのVPC Lambdaと非VPC Lambdaの違い」参照ください
非VPCでRDSのセキュリティグループのポート3306のソース元を0.0.0.0/0にしていると現状SQLを発行できています。参考サイト
但し、Lambdaを2回実行するとエラーになります。これはRDSと同一のVPCにLambdaを指定してアクセス権限を与えても発生しました。
ソースは以下の通り。
const aws = require("aws-sdk"); const mysql = require('mysql'); const conn = mysql.createConnection({ host : 'db.xxxxxxxxx.us-east-2.rds.amazonaws.com',// RDSのエンドポイント user : 'xxxx', password : 'xxxx', database : 'xxxx' }); exports.handler = (event, context, callback) => { const q = conn.query('SELECT * FROM dbname.table1'); q.on('error', function(err) { console.log(err); }).on('result', function(rows) { console.log("SQL結果:" + JSON.stringify(rows)); }).on('end', function(err) { console.log('end'); conn.end(); }); };
mysql2
mysql2というモジュールがあるようです。
インストールは以下の通り。
npm install mysql2
end()メソッドが不要でほぼ使い方は同じみたいです。
ADS SDK for javascript v3でmysql互換(serverless v1)のAuroraに接続する 2022/07/02
“HttpEndpoint is not enabled for cluster database-xxx. Please refer to https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html#data-api.troubleshooting”,
このエラーが出たのでDataBaseはserverless v1(Aurora 2.07.1)にして「Data API」にチェックを入れました。プライベートサブネットに配置します。
これで作成すると、ロールが「サーバーレス」と表示されます。
シークレットを作成します。(※タイムラグがありますが、勝手に作成されるので省略可)
DBにuserテーブル作成し、レコード1行インサートしています。
サーバーレスLambdaです。
npm i @aws-sdk/client-rds-data
このモジュールをzip圧縮してLambdaデプロイしています。
import { RDSDataClient, ExecuteStatementCommand } from '@aws-sdk/client-rds-data' export async function handler(event, context) { const client = new RDSDataClient({ region: 'ap-northeast-1' }) const params = { sql: 'select * from test.user', resourceArn: 'arn:aws:rds:ap-northeast-1:xxxxxxxxxxxx:cluster:database-xxx', secretArn: 'arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:rds-db-credentials/cluster-xxxxxxxxxxxxxxxxxxxxxxxxxxxx' }; const command = new ExecuteStatementCommand(params) const responses = await client.send(command) console.log('responses start') console.log(responses.records[0][0].longValue) console.log(responses.records[0][1].stringValue) console.log('responses end') const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; };
SQLが発行され、ログが表示されています。Data APIを使用すればサーバレスLambdaからアクセスすることができるようです。
参考サイト
serverless v2でLambdaから接続 2022/07/03
プライベートサブネットに配置したServerless v2のRDS(MySQL)にサーバレスLambdaで接続できるかを試してみました。
mysql接続にはpromise-mysqlを使用しています。
import * as mysql from 'promise-mysql' const conn = await mysql.createConnection({ host : 'データベースエンドポイント', port: 3306, user : 'ユーザ名', password : 'パスワード', database : 'mysql' }) export async function handler(event, context) { let results = await conn.query('SELECT * FROM db') console.log(results) conn.end() const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; };
コネクションタイムアウトでエラーが出たので無理でした。VPC上にLambdaを配置したら接続できました。
現時点でserverless v2はデータAPIを使用することができないようです。
参考サイト
KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント