Reputation: 1460
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