5
votes

I am developing an application where I need to schedule a task, so I am using AWS Lambda for it.However, the scheduled time is dynamic, since it depends on the user request, it can't be scheduled using AWS Console, so I use AWS Javascript SDK to schedule it. This is the flow:

  1. Create a CloudWatch Rule (this is successful, I can see the rule being created in the console
  2. Add permission to the policy of lambda, so that cloudwatch event can invoke it (Lambda function code is same for all request, so I created a lambda function in AWS Console instead of using SDK)
  3. Add target to the rule created in Step 1 (this step fails). The error i get is RoleArn is not supported for target arn:aws:lambda:eu-west-1:629429065286:function:prebook.

Below is the Node.js code I wrote

schedule_aws_lambda: function(booking_id, cronTimeIST, callback){
      var event = new AWS.CloudWatchEvents({
        accessKeyId: accessKeyId,
        secretAccessKey: secretAccessKey,
        region: 'eu-west-1'
      });

      var lambda = new AWS.Lambda({
        accessKeyId: accessKeyId,
        secretAccessKey: secretAccessKey,
        region: 'eu-west-1'
      });

      var year = cronTimeIST.utc().year();
      var month = cronTimeIST.utc().month() + 1;
      var date = cronTimeIST.utc().date();
      var hour = cronTimeIST.utc().hour();
      var minute = cronTimeIST.utc().minute();
      var cronExpression = "cron(" + minute + " "+ hour + " " + date + " " + month + " ? " + year +")";
      var hour_minute = cronTimeIST.format("HH_mm");
      var ruleParams = {
        Name: 'brodcast_' + booking_id + '_' + hour_minute,
        Description: 'prebook brodcast for ' + booking_id + '_' + hour_minute,
        ScheduleExpression: cronExpression, 
        RoleArn: 'arn:aws:iam::629429065286:role/service-role/prebook_lambda_role',
        State: 'ENABLED',
      };
      event.putRule(ruleParams).promise()
      .then(data => {
        var lambdaPermission = {
          FunctionName: 'arn:aws:lambda:eu-west-1:629429065286:function:prebook',
          StatementId: 'brodcast_' + booking_id + '_' + hour_minute,
          Action: 'lambda:*',
          Principal: 'events.amazonaws.com', 
        };
        return lambda.addPermission(lambdaPermission).promise();
      })
      .then(data => {
        var targetParams = {
          Rule: ruleParams.Name,
          Targets: [
            {
              Id: 'default',
              Arn: 'arn:aws:lambda:eu-west-1:629429065286:function:prebook',
              RoleArn: ruleParams.RoleArn,
              Input: JSON.stringify({booking_id: booking_id})
            }
          ]
        };
        return event.putTargets(targetParams).promise();
      })
      .then(data => {
        callback(null, data);
      })
      .catch(err => {
        callback(err)
      });  
    }

I know it has to do something with the Role which doesn't have some permission, I can't figure out the exact cause, I have given the following access for the role enter image description here

And this is the policy document

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Basically, I want to attach many triggers(the trigger time is not known to me it depends on user request) to the lambda function, however, lambda function code is same for all.

1
Did you ever get anywhere with this?Joseph Carroll
No, currently we are scheduling with node-cron instead of lambda , however, that's not the right way, since cron schedule will be lost if the server crashes or restarts. We are trying alternative solutions like Firebase cloud functions and Firebase DB.vikneshwar

1 Answers

14
votes

Try removing the RoleArn property. If you are adding permissions to the Lambda function to allow CloudWatch events to invoke it, you don't need it.

In the function policy, make sure you add the SourceArn of the event.