微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Lambda功能完成后,Amazon Cloudformation堆栈挂起

如何解决Lambda功能完成后,Amazon Cloudformation堆栈挂起

我有一个简单的模板来创建S3存储桶,然后调用Lambda函数从公共存储桶中将对象复制到其中:

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,response.SUCCESS,{})
};

堆栈成功创建并引导了新的存储桶,但是堆栈历史显示DeploymentCustomresource资源永远不会超过CREATE_IN_PROGRESS状态,即使lambda日志显示功能已成功完成。我尝试了使用回调的各种替代方法,并将该函数减少为不执行任何操作,但堆栈始终挂起。

有什么建议吗?

解决方法

您的函数卡在CREATE_IN_PROGRESS中,因为CloudFormation(CFN)等待该函数的正确响应。您的代码没有提供它。

自定义资源的功能需要特殊设计。必须正确处理CFN事件,并做出相应的响应。

对于nodejs中的函数,您可以使用 helper库 cfn-response,如cfn-response module所示。 here是nodejs中托管资源功能的示例。

,

我认为问题是因为handler是异步的。

这是工作功能:

const AWS = require('aws-sdk');
const response = require('cfn-response');

const s3 = new AWS.S3();
const srcBucket = "mongodb-aws-jam"
const srcKey = "SampleData.csv"

exports.handler = function(event,context) {
  var bucket = event.ResourceProperties.bucketname;
  console.log(`Bucket: ${bucket}`);
  const copyparams = {
    Bucket : bucket,CopySource : `/${srcBucket}/${srcKey}`,Key : srcKey
  };
  s3.copyObject(copyparams).promise()
  .then (() => {
      var responseData = {Value: bucket};
      console.log("Success");
      response.send(event,context,response.SUCCESS,responseData);
  },error => {
      const errorText = `Failed to copy file to ${bucket}/${srcKey}: ${error}`
      console.log(errorText)
      response.send(event,response.FAILED,{Error: errorText})
  })
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。