使用 Lambda 的自定义触发器更新 AWS CloudFormation

Updating an AWS CloudFormation with a custom trigger for Lambda

一个团队成员和我有一个 CloudFormation 堆栈,其中包含 nodejs Lambda 支持的自定义资源。

更新 lambda/parameters/trigger 后,我们希望 Lambda 首先删除它创建的第 3 方资源,然后根据新参数创建新资源。

这是我们的 exports.handler 的 lambda。

if (event.RequestType == "Delete") {
    console.log("Request type == Delete")
    var successCallback = function(event, context) {
        sendResponse(event, context, "SUCCESS");
    }
    doDeleteThings(event, context, successCallback);
} else if (event.RequestType == "Create") {
    console.log("request type == create")
    doCreateThings(event, context);
} else if (event.RequestType == "Update") {
    console.log("request type == update")
    var successCallback = function(event, context) {
        doCreateThings(event, context);
    }
    doDeleteThings(event, context, successCallback);
} else {
    sendResponse(event, context, "SUCCESS");
}

我们已经测试了代码,它适用于 CloudFormation 中的创建和删除,以及无堆栈模式中的创建、删除和更新(我们设置:event.RequestType = process.env.RequestType 并且 sendResponse 不'不执行通常的 CloudFormation 响应 POSTing,而只是执行 context.done()),但我们似乎无法使其在 CloudFormation 中进行更新。我开始认为我们误解了 Lambda 上的 'update' 应该做什么。

我们之前从未能够看到由 CloudFormation 创建的 Lambda 函数的 CloudWatch 日志,这无济于事。

这里是 CloudFormation 模板的相关部分:

   "ManageThirdPartyResources": {
        "Type": "AWS::Lambda::Function",
        "Properties": {
            "Code": {
                "S3Bucket": "<bucketname>",
                "S3Key": "<zipname>.zip"
            },
            "Description": { "Fn::Join": ["", ["Use cloudformation to automatically create third party resources for the ", { "Ref": "ENV" }, "-", { "Ref": "AWS::StackName" }, " environment"]] },
            "Environment": {
                "Variables": {
                    <environment variables that will probably be the things changing.>
                }
            },
            "FunctionName": {
                "Fn::Join": ["_", [{ "Ref": "AWS::StackName" }, "ManageThirdPartyResources"]]
            },
            "Handler": "index.handler",
            "Role": "<role>",
            "Runtime": "nodejs4.3",
            "Timeout": 30
        }
    },
    "ThirdPartyResourcesTrigger": {
        "Type": "Custom::ThirdPartyResourcesTrigger",
        "Properties": {
            "ServiceToken": { "Fn::GetAtt": ["ManageThirdPartyResources", "Arn"] }
        }
    },

谢谢!

如果 它的 属性之一发生变化,将在您的 Custom::ThirdPartyResourcesTrigger 上触发更新。如果 Lambda 函数的属性发生变化,它将 不会 触发对 Custom::ThirdPartyResourcesTrigger.

的更新

所以如果你想在Custom::ThirdPartyResourcesTrigger上触发更新,你必须修改它的属性。例如,您可以向 ThirdPartyResourcesTrigger 添加一个名为 ThingName 的 属性,每当您更改 ThingName 的值时,您的 Lambda 将使用 Update 调用请求类型:

"ThirdPartyResourcesTrigger": {
    "Type": "Custom::ThirdPartyResourcesTrigger",
    "Properties": {
        "ServiceToken": { "Fn::GetAtt": ["ManageThirdPartyResources", "Arn"] },
        "ThingName": "some value"
    }
},

关于日志记录,请确保您的 Lambda 函数承担的 IAM 角色具有 CloudWatch 日志所需的权限:

"Effect": "Allow"
"Action": "logs:*"
"Resource": "arn:aws:logs:*:*:*"