【问题标题】:Aws lambda function addPermission error: PolicyLengthExceededExceptionAws lambda 函数 addPermission 错误:PolicyLengthExceededException
【发布时间】:2018-06-09 17:25:23
【问题描述】:

我正在创建一个 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 事件提醒。

【问题讨论】:

  • 您正在为每个需要触发的事件创建一个事件?由于其他原因,我认为这不会扩大规模。似乎更好的策略是每 5 分钟触发一次并查询表(例如 DynamoDB 或 RDS)以查看哪些未发送的通知需要“现在”发送,然后通过调用第二个来处理它们。 Lambda 函数。想法?
  • 由于对我可以拥有的 cloudwatch 事件数量的限制,最终做到了:(

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


【解决方案1】:

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

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

【讨论】:

  • 这确实是解决问题的正确方法。但是,事实证明,预定事件的最大数量也有限制 (100)。所以最终做了@michael-sqlbot 建议的事情
猜你喜欢
  • 1970-01-01
  • 2018-07-11
  • 2020-09-03
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 2016-01-11
  • 1970-01-01
  • 2022-10-23
相关资源
最近更新 更多