Aws lambda Amazon Cloudformation堆栈在Lambda函数完成后挂起
我有一个简单的模板来创建一个S3 bucket,然后调用Lambda函数将一个对象从公共bucket复制到它:Aws lambda Amazon Cloudformation堆栈在Lambda函数完成后挂起,aws-lambda,amazon-cloudformation,Aws Lambda,Amazon Cloudformation,我有一个简单的模板来创建一个S3 bucket,然后调用Lambda函数将一个对象从公共bucket复制到它: AWSTemplateFormatVersion: 2010-09-09 Transform: AWS::Serverless-2016-10-31 Description: Create an S3 Bucket, populate it with a copy of a sample CSV file Parameters: bucketname: Type: Stri
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: Create an S3 Bucket, populate it with a copy of a sample CSV file
Parameters:
bucketname:
Type: String
Description: Name of bucket where the CSV file will be bootstrapped, bucket names MUST be unique across AWS and no Upper Case characters - 8 or more characters
MinLength: 8
Outputs:
bucketURL:
Value:
Fn::Join:
- ''
- - 'https://s3.amazonaws.com/'
- !Ref bucketname
Resources:
S3Bucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
Properties:
BucketName: !Ref bucketname
deploytos3:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs12.x
CodeUri: 's3://mongodb-aws-jam/lambdaDeploy.zip'
Policies:
- AWSLambdaBasicExecutionRole
- AmazonS3FullAccess
DeploymentCustomResource:
Type: Custom::deploytos3
Properties:
ServiceToken: !GetAtt deploytos3.Arn
bucketname: !Ref bucketname
这是Lambda函数:
const AWS = require('aws-sdk');
var response = require('cfn-response');
const s3 = new AWS.S3();
const srcBucket = "mongodb-aws-jam"
const srcKey = "SampleData.csv"
exports.handler = async (event, context) => {
console.log("start")
myBucket = event.ResourceProperties['bucketname']
console.log(`Will bootstrap ${srcKey} object in ${myBucket} bucket`)
const copyparams = {
Bucket : myBucket,
CopySource : `/${srcBucket}/${srcKey}`,
Key : srcKey
};
try {
await s3.copyObject(copyparams).promise();
} catch (error) {
const errorText = `Failed to copy file to ${myBucket}/${srcKey}: error`
console.log(errorText)
// callback(null, {statusCode: 500, body: errorText})
response.send(event, context, response.FAILED, {Error: errorText})
return
}
resultText = `Copied file to ${myBucket}/${srcKey}`
console.log(resultText)
// callback(null, {statusCode: 200, body: resultText})
response.send(event, context, response.SUCCESS, {})
};
堆栈成功地创建和引导了新的bucket,但是堆栈历史显示DeploymentCustomResource
资源从未超过CREATE\u in\u PROGRESS
状态,即使lambda日志显示函数已成功完成。我尝试过使用回调的各种替代方法,并将函数简化为不做任何工作,但堆栈总是挂起
有什么建议吗?由于CloudFormation(CFN)等待函数的正确响应,您的函数陷入了创建过程中。您的代码没有提供它 自定义资源的功能需要特殊设计。必须正确处理CFN事件,并做出相应的响应
对于nodejs中的函数,可以使用助手库
cfn response
,如中所示。nodejs中的custom资源函数的例子有。我认为问题是因为handler
是异步的
这是工作功能:
const AWS = require('aws-sdk');
var response = require('cfn-response');
const s3 = new AWS.S3();
const srcBucket = "mongodb-aws-jam"
const srcKey = "SampleData.csv"
exports.handler = async (event, context) => {
console.log("start")
myBucket = event.ResourceProperties['bucketname']
console.log(`Will bootstrap ${srcKey} object in ${myBucket} bucket`)
const copyparams = {
Bucket : myBucket,
CopySource : `/${srcBucket}/${srcKey}`,
Key : srcKey
};
try {
await s3.copyObject(copyparams).promise();
} catch (error) {
const errorText = `Failed to copy file to ${myBucket}/${srcKey}: error`
console.log(errorText)
// callback(null, {statusCode: 500, body: errorText})
response.send(event, context, response.FAILED, {Error: errorText})
return
}
resultText = `Copied file to ${myBucket}/${srcKey}`
console.log(resultText)
// callback(null, {statusCode: 200, body: resultText})
response.send(event, context, response.SUCCESS, {})
};
const AWS=require('AWS-sdk');
const response=require('cfn-response');
const s3=新的AWS.s3();
const srcBucket=“mongodb aws jam”
const srcKey=“SampleData.csv”
exports.handler=函数(事件、上下文){
var bucket=event.ResourceProperties.bucketname;
log(`Bucket:${Bucket}`);
常量copyparams={
桶:桶,
CopySource:`/${srcBucket}/${srcKey}`,
密钥:srcKey
};
s3.copyObject(copyparams.promise())
.然后(()=>{
var responseData={Value:bucket};
控制台日志(“成功”);
response.send(事件、上下文、response.SUCCESS、responseData);
},错误=>{
const errorText=`未能将文件复制到${bucket}/${srcKey}:${error}`
console.log(errorText)
send(事件、上下文、response.FAILED,{Error:errorText})
})
};
我也尝试了cfn response
,例如var response=require('cfn-response')。。。response.send(event,context,response.SUCCESS,{})
但自定义资源仍处于CREATE\u in\u PROGRESS
状态。@AndrewMorgan添加var response=require('cfn-response')
是不够的。您必须完全重新编写函数以符合CFN自定义资源格式。我建议检查文档和示例如何设计这些函数。我通过调用response.send(event,context,response.SUCCESS,{})来遵循示例。我在日志中看到响应正文:{“状态”:“成功”,“原因”:“查看CloudWatch日志流中的详细信息:2020/10/12/[$LATEST]…
。还缺少什么?@AndrewMorgan您可以用新版本的代码更新您的问题吗?@AndrewMorgan我想您已经将cfn响应
模块与您的函数捆绑在一起了?