AWS Lambda和RDS工作示例(需要与Sequelize一起使用)

时间:2018-07-10 21:12:05

标签: mysql node.js amazon-web-services aws-lambda sequelize.js

这是AWS Lambda和MySQL的有效示例,但我希望它可以与Sequelize一起使用。如何初始化Sequelize以与AWS Lambda一起使用?我也具有经过身份验证的IAM角色。

https://dzone.com/articles/passwordless-database-authentication-for-aws-lambd

'use strict';
const mysql = require('mysql2');
const AWS = require('aws-sdk');
// TODO use the details of your database connection
const region = 'eu-west-1';
const dbPort = 3306;
const dbUsername = 'lambda'; // the name of the database user you created in step 2
const dbName = 'lambda_test'; // the name of the database your database user is granted access to
const dbEndpoint = 'lambdatest-cluster-1.cluster-c8o7oze6xoxs.eu-west-1.rds.amazonaws.com';
module.exports.handler = (event, context, cb) => {
  var signer = new AWS.RDS.Signer();
  signer.getAuthToken({ // uses the IAM role access keys to create an authentication token
    region: region,
    hostname: dbEndpoint,
    port: dbPort,
    username: dbUsername
  }, function(err, token) {
    if (err) {
      console.log(`could not get auth token: ${err}`);
      cb(err);
    } else {
      var connection = mysql.createConnection({
        host: dbEndpoint,
        port: dbPort,
        user: dbUsername,
        password: token,
        database: dbName,
        ssl: 'Amazon RDS',
        authSwitchHandler: function (data, cb) { // modifies the authentication handler
          if (data.pluginName === 'mysql_clear_password') { // authentication token is sent in clear text but connection uses SSL encryption
            cb(null, Buffer.from(token + '\0'));
          }
        }
      });
      connection.connect();
      // TODO replace with your SQL query
      connection.query('SELECT * FROM lambda_test.test', function (err, results, fields) {
        connection.end();
        if (err) {
          console.log(`could not execute query: ${err}`);
          cb(err);
        } else {
          cb(undefined, results);
        }
      });
    }
  });
};

2 个答案:

答案 0 :(得分:1)

而不是使用 mysql.createConnection() 并使用您的 RDS 签名者令牌:

var sequelize = require('sequelize')
const Sequelize = new sequelize(
        process.env.database_name,
        process.env.databse_user,
        token,
        {
            dialect: 'mysql',
            dialectOptions: {
                ssl: 'Amazon RDS',
                authPlugins: { // authSwitchHandler is deprecated
                    mysql_clear_password: () => () => {
                        return token
                    }
                }
            },
            host: process.env.db_proxy_endpoint,
            port: process.env.db_port,
            pool: {
                min: 0, //default
                max: 5, // default
                idle: 3600000
            },
            define: {
                charset: 'utf8mb4'
            }
        }
// then return your models (defined in separate files usually) 
await Sequelize.authenticate() // this just does a SELECT 1+1 as result;
await Sequelize.sync() // DO NOT use this in production, this tries to create tables defined by your models. Consider using sequelize migrations instead of using sync()

此外,将您的数据库连接参数保存在配置文件中也是一个好主意,这样任何人都无法看到它们。 (process.env)

答案 1 :(得分:0)

我们正在与Sequelize和Lambda合作,但是您将需要保留更多资源,在我们的情况下,我们至少需要1GB才能与Sequelize运行lambda。没有它,仅使用mysql2即可运行128MB。

但是,如果您真的想使用Sequelize,只需将您的createConnection替换为sequelize doc中的内容

您可能会使用context.callbackWaitsForEmptyEventLoop=true,因为调用回调函数时可能会遇到一些问题,而您却一无所获,因为您的事件循环可能永远不会为空。