Shrouk Khan
Shrouk Khan

Reputation: 1460

Aws lambda function addPermission error: PolicyLengthExceededException

I am creating a cloudwatch event which at a specific time in future is supposed to call a aws lambda function . The i am using aws nodejs sdk as described here: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html

the code block to create the cloudwatch event looks like this:

 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)
                                }
                            })
                        }
                    })
                })
            }
        });
    })


})

}

Above function works fine for the first ~50 times ( so I can easily make reminder for the 50 reservations. ) However , it will always fail eventually with:

PolicyLengthExceededException Lambda function access policy is limited to 20 KB.

HTTP Status Code: 400

Which makes sense, as policy document can not be too big. So what is the correct way to approach this problem : make unlimited cloudwatch event reminder with a lambda function target .

Upvotes: 4

Views: 2920

Answers (1)

owais
owais

Reputation: 4922

create a role and add that policy or permission for that role and then your lambda can assume role and run. you can use aws STS module for that.

Rather than create and removing permission each time. STS will assume role temporarily then execute the code.

Upvotes: 2

Related Questions