简体   繁体   中英

AWS SDK can't add Lambda as target to Cloudwatch event

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在此处输入图像描述

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.

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.

Here's the reference from the docs that explains the error. You must use a resource policy (= Lambda permission), not an identity policy (= role) to invoke Lambda from EventBridge:

Docs : Amazon SQS, Amazon SNS, Lambda, CloudWatch Logs, and EventBridge bus targets do not use roles, and permissions to EventBridge must be granted via a resource policy. API Gateway targets can use either resource policies or IAM roles.

The Lambda AddPermission API creates the resource policy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM