将Cloudformation模板中自定义资源支持的lambda从6.10更新到8.10不再发送请求

时间:2019-05-21 05:26:19

标签: node.js aws-lambda amazon-cloudformation

我们使用cloudformation模板为我们的客户提供了我们软件的试用版,以启动AWS AMI。最近,我向此模板添加了一个自定义资源,该资源生成了一个试用许可证密钥,可在试驾期间使用,并保存一个cloudformation输出。通过运行存储在S3上的lambda zip文件来生成许可证。它首先在node4.10中工作,然后在node6.10中工作,但是现在我已移至node8.10,等待来自parsedUrl的响应的步骤在收到响应之前结束。由于没有响应返回给cloudformation,因此如果该资源等待60分钟,则创建该对象,然后发出delete stack命令的信号。

我相信问题在于nodejs的异步特性,以及我对如何转换代码缺乏了解。

exports.handler = (event, context) => {

return genKey("./lic_wrp.sh", [arg1]).then(function(resp) {
    responseStatus = "SUCCESS";
    responseData["trialkey"] = resp;
    console.log ('Here is the response', responseData);

    sendResponse(event, context, responseStatus, responseData);
  }
);

该代码段是原始的node6.10工作版本。 我已更改为:

exports.handler = async (event,context) => {

try {
  var resp = await helpers.genKey("./lic_wrp.sh", [arg1]);
  responseStatus = "SUCCESS";
  responseData["trialkey"] = resp;
  console.log ('Here is the response', responseData);
  try {
    const rest2 = await sendResponse(event,  context, responseStatus, responseData)
    return rest2;
  } catch (e){
    console.log(e);
  }
} catch (e){
  console.log(e);
}

sendResponse代码保持不变,我使用了AWS站点中的示例:

function sendResponse(event, context, responseStatus, responseData) {

    var responseBody = JSON.stringify({
        StackId: event.StackId,
        RequestId: event.RequestId,
        LogicalResourceId: event.LogicalResourceId,
        PhysicalResourceId: context.logStreamName,
        Status: responseStatus,
        Reason: "See the details in CloudWatch Log " + context.logStreamName,
        Data: responseData
    });

    console.log("RESPONSE BODY:\n", responseBody);

    var https = require("https");
    var url = require("url");

    var parsedUrl = url.parse(event.ResponseURL);
    var options = {
        hostname: parsedUrl.hostname,
        port: 443,
        path: parsedUrl.path,
        method: "PUT",
        headers: {
            "content-type": "",
            "content-length": responseBody.length
        }
    };

    console.log("SENDING RESPONSE...\n");

    var request = https.request(options, function(response) {
        console.log("STATUS: " + response.statusCode);
        console.log("HEADERS: " + JSON.stringify(response.headers));
        // Tell AWS Lambda that the function execution is done
        context.done();
    });

    request.on("error", function(error) {
        console.log("sendResponse Error:\n", error);
        // Tell AWS Lambda that the function execution is done
        context.done(error);
    });

  request.write(responseBody);
  request.end();
}

在cloudwatch中,我看到responseBody仍然很好。

2019-05-21T05:02:50.450Z    ba8542ed-66cf-4ada-9ae6-fd4f1920faee    RESPONSE BODY:
{
    "StackId": "arn:aws:cloudformation:ap-southeast-2:267176467350:stack/laatest52/9c35f740-7b85-11e9-9ba3-0217b90f9ac8",
    "RequestId": "1eafeb08-fadc-4bc5-a476-19330599ad6d",
    "LogicalResourceId": "LicenseKey",
    "PhysicalResourceId": "2019/05/21/[$LATEST]e2cc667849d44285b452af5fa31084b2",
    "Status": "SUCCESS",
    "Reason": "See the details in CloudWatch Log 2019/05/21/[$LATEST]e2cc667849d44285b452af5fa31084b2",
    "Data": {
        "trialkey": "xxxx-xxxx-xxxx-xxxx-xxxx" -- Our key gen is working
    }
}

然后我看到正在发送回复。 但是下一行是: END RequestId: ba8542ed-66cf-4ada-9ae6-fd4f1920faee

在以前的版本中效果很好。 我们看到响应主体,然后发送响应: 2018-11-16T18:03:06.435Z dd879acf-e9c9-11e8-afaf-bfffb4a386b6 STATUS: 200

资源已创建。

1 个答案:

答案 0 :(得分:0)

回答了自己的问题。 安装了“ cfn-response-promise”模块,它是我正在使用的sendResponse函数的异步/等待兼容替代方法。 CF堆栈完整无误地运行,并且在运行lambda之后收到STATUS 200。