Pea*_*Gen 5 amazon-web-services node.js aws-cloudformation aws-lambda aws-api-gateway
我正在使用 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)
});
};
Run Code Online (Sandbox Code Playgroud)
这是相同的代码,但现在使用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)
});
});
};
Run Code Online (Sandbox Code Playgroud)
这是我的云形成文件
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: '*'
Run Code Online (Sandbox Code Playgroud)
我的代码没有AWS SecretsManager在部署时工作正常。
然而,当部署和测试 API 调用时,代码AWS SecretsManager给出了。我只是打电话timeout errorPOSTMAN
https://*****.****-api.****-1.amazonaws.com/Prod/role/getall
"message": "Endpoint request timed out"即使在控制台中,我也只看到了其他内容。使用 执行时相同的代码可以正常工作sam invoke local GetAllRolesFunction。测试时也很好sam local start-api。仅当上传到 AWS 并进行 API 调用时才会出现此问题。
这里发生了什么?
来自 API Gateway 的错误消息“端点请求超时”表明您的 API 调用的 Lambda 函数完成时间超过 29 秒。
我猜测您的 Lambda 函数正在 VPC 中运行,并且您已正确设置到(私有)RDS 数据库的网络路由,但您没有到 Secrets Manager 服务端点的网络路由,因此该请求超时。如果是这样,您需要Secrets Manager 的 VPC 终端节点或路由到公共互联网的 NAT(或 NAT 网关)。
| 归档时间: |
|
| 查看次数: |
19641 次 |
| 最近记录: |