Aws lambda函数addPermission错误:PolicyLengthExceededException

时间:2017-12-29 08:36:17

标签: amazon-web-services aws-lambda aws-sdk amazon-iam amazon-cloudwatch

我正在创建一个cloudwatch事件,在将来的某个特定时间应该调用aws lambda函数。我正在使用aws nodejs sdk,如下所述:http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html

创建cloudwatch事件的代码块如下所示:

 module.exports.createReservationReminder = function (reservationModel, user, restaurant) {
return new Promise(function (resolve, reject) {
    const ruleName = "rsv_" + reservationModel.reservationId;
    const description = "Reservation reminder of `" + user.name + "` @ `" + restaurant.title + "` on `" + reservationModel.time + "`";
    let reservationTime = reservationModel.time;
    let lambdaFunctionName = module.exports.buildLamdaFunctionArn("restaurant")

    let alertTime = moment(reservationTime).tz(AppConfig.defaultTimezone).subtract( // Create alert 45 minute before a reservation
            45,
            'minutes'
        );

    let lambda = new AWS.Lambda({
        accessKeyId: AppConfig.accessKeyId,
        secretAccessKey: AppConfig.secretAccessKey,
        region: AppConfig.region
    });

    let scheduleExpression1 = "cron(" + alertTime.utc().format('m H D MMM ? YYYY') + ')';

    let ruleParams = {
        Name: ruleName, 
        Description: description,
        ScheduleExpression: scheduleExpression1,
        State: 'ENABLED',
    };
    cloudwatchevents.deleteRule({Name: ruleName}, function (err, deleteRuleData) { //remove if a previous rule was created halfway
        cloudwatchevents.putRule(ruleParams, function (err, ruleData) {  //create the rule 
            if (err) {
                reject(err)
            }
            else {


                let lambdaPermission = {
                    FunctionName: lambdaFunctionName,
                    StatementId: ruleName,
                    Action: 'lambda:InvokeFunction',
                    Principal: 'events.amazonaws.com',
                    SourceArn: ruleData.RuleArn
                };

                let removePermission = {
                    FunctionName: lambdaFunctionName,
                    StatementId: ruleName,
                }

                //now to create the rule's target, need to add permission to lambda
                lambda.removePermission(removePermission, function (err, removeLambdaData) { //remove if rule of same name was added as permission to this lambda before, ignore if rule not found error is thrown
                    lambda.addPermission(lambdaPermission, function (err, lamdaData) { //now add the permission
                        if (err) {
                            reject(err) // FAIL : throws error  PolicyLengthExceededException after ~50 cloudwatch events are registered to this lambda function
                        }
                        else {
                            let targetParams = {
                                Rule: ruleName,
                                Targets: [
                                    {
                                        Arn: module.exports.buildLamdaFunctionArn("restaurant"), 
                                        Id: ruleName, 
                                        Input: JSON.stringify({
                                            func: "notifyUserOfUpcomingReservation",
                                            data: {
                                                reservationId: reservationModel.reservationId
                                            }
                                        }),

                                    },

                                ]
                            };
                            cloudwatchevents.putTargets(targetParams, function (err, targetData) {
                                if (err) {
                                    reject(err)
                                }
                                else {
                                    resolve(targetData)
                                }
                            })
                        }
                    })
                })
            }
        });
    })


})

}

以上功能在前50次正常工作(因此我可以轻松提醒50次预订。)但是,它最终总会失败:

PolicyLengthExceededException Lambda函数访问策略限制为20 KB。

HTTP状态代码:400

这是有道理的,因为政策文件不能太大。 那么解决这个问题的正确方法是什么:使用lambda函数目标制作无限制的cloudwatch事件提醒。

1 个答案:

答案 0 :(得分:1)

创建角色并为该角色添加该策略或权限,然后您的lambda可以承担角色并运行。 你可以使用aws STS模块。

而不是每次都创建和删除权限。 STS将暂时承担角色然后执行代码。