【发布时间】:2021-09-29 20:36:11
【问题描述】:
我正在使用 AWS Lambda、API Gateway、RDS (MySQL) 开发一个 REST API。我正在使用 Node.js。
这是我的普通 AWS Lambda 代码,调用数据库表来获取数据并通过 REST API 发送。
const mysql = require('mysql');
const con = mysql.createConnection({
host : "****.****.****.rds.amazonaws.com",
user : "****",
password : "****",
port : 3306,
database : "****"
});
exports.getAllRoles = (event, context, callback) => {
// allows for using callbacks as finish/error-handlers
context.callbackWaitsForEmptyEventLoop = false;
const sql = "select * from role";
con.query(sql, function (err, result) {
if (err) throw err;
var response = {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": JSON.stringify(result),
"isBase64Encoded": false
};
callback(null, response)
});
};
这是相同的代码,但现在使用AWS SecretsManager
const mysql = require('mysql');
// Load the AWS SDK
var AWS = require('aws-sdk'),
region = "us-east-1",
secretName = "test-secret",
secret,
decodedBinarySecret;
// Create a Secrets Manager client
var client = new AWS.SecretsManager({
region: region
});
exports.getAllRoles = (event, context, callback) => {
client.getSecretValue({
SecretId: secretName
}, function (err, data) {
if (err) {
throw err;
} else {
// Decrypts secret using the associated KMS CMK.
// Depending on whether the secret is a string or binary, one of these fields will be populated.
if ('SecretString' in data) {
secret = data.SecretString;
} else {
let buff = new Buffer(data.SecretBinary, 'base64');
decodedBinarySecret = buff.toString('ascii');
}
}
// Your code goes here.
const secretObj = JSON.parse(secret);
//Create MySQL Connection
const con = mysql.createConnection({
host : secretObj.host,
user : secretObj.user,
password : secretObj.password,
port : secretObj.port,
database : secretObj.database
});
// allows for using callbacks as finish/error-handlers
context.callbackWaitsForEmptyEventLoop = false;
const sql = "select * from role";
con.query(sql, function (err, result) {
if (err) throw err;
var response = {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": JSON.stringify(result),
"isBase64Encoded": false
};
callback(null, response)
});
});
};
这是我的云生成文件
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aaaa-restapi
Sample SAM Template for aaaa-restapi
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 100
VpcConfig:
SecurityGroupIds:
- sg-4424242424
SubnetIds:
- subnet-424242424242
Resources:
GetAllRolesFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aaaa-restapi/
Handler: role-getall.getAllRoles
Runtime: nodejs14.x
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /role/getall
Method: get
LambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:DescribeNetworkInterfaces
- ec2:CreateNetworkInterface
- ec2:DeleteNetworkInterface
- ec2:DescribeInstances
- ec2:AttachNetworkInterface
Resource: '*'
没有AWS SecretsManager 的代码在部署时工作正常。
但是,AWS SecretsManager 的代码在使用POSTMAN 部署和测试 API 调用时给出了timeout error。我只是打电话
https://*****.****-api.****-1.amazonaws.com/Prod/role/getall
我只看到"message": "Endpoint request timed out" 而没有其他任何东西,即使在控制台中也是如此。使用sam invoke local GetAllRolesFunction 执行时,相同的代码运行良好。用sam local start-api 测试时也很好。该问题仅在上传到 AWS 并进行 API 调用时出现。
这里发生了什么?
【问题讨论】:
标签: node.js amazon-web-services aws-lambda amazon-cloudformation aws-api-gateway