Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CreateScheduleCommand throws invalid ValidationException #6494

Open
3 of 4 tasks
defmtog opened this issue Sep 19, 2024 · 14 comments
Open
3 of 4 tasks

CreateScheduleCommand throws invalid ValidationException #6494

defmtog opened this issue Sep 19, 2024 · 14 comments
Assignees
Labels
bug This issue is a bug. p2 This is a standard priority issue

Comments

@defmtog
Copy link

defmtog commented Sep 19, 2024

Checkboxes for prior research

Describe the bug

When I create a valid Policy, Role, AssumeRolePolicy and Group and send the command I get the following error:
ValidationException: The execution role you provide must allow AWS EventBridge Scheduler to assume the role.

If a add a bogus AssumeRolePolicy to the Permission Policy it succeeds. Seems the validation is looking for the AssumeRolePolicy in the PermissionPolicy rather than in the AssumeRolePolicy?

example code:


Regression Issue

  • Select this option if this issue appears to be a regression.

SDK version number

@aws-sdk/[email protected]

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

v20.17.0

Reproduction Steps

const iamClient = new IAMClient(initial)
  const assumePolicy = {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Principal": {
          "Service": "scheduler.amazonaws.com"
        },
        "Action": "sts:AssumeRole",
        "Condition": {
          "StringEquals": {
            "aws:SourceAccount": `${config.aws_account_id}`
          }
        }
      }
    ]
  }
  console.log(JSON.stringify(assumePolicy))
  const inputR = { // CreateRoleRequest
    RoleName: `Amazon_EventBridge_Scheduler_${lambdaLongName}`,
    AssumeRolePolicyDocument: JSON.stringify(assumePolicy),
    Description: `Execution role for ${lambdaLongName}`
  }
  const command = new CreateRoleCommand(inputR)
  return iamClient.send(command).then(role => {
    console.log('role:', role)
    return role.Role
  }).then(role => {
    // create policy
    const policyStatement = {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "lambda:InvokeFunction"
          ],
          "Resource": [
            `${lambdaArn}:*`,
            `${lambdaArn}`
          ]
        },
        // add Bogus AssumeRole
        // {
        //   "Effect": "Allow",
        //   "Action": "sts:AssumeRole",
        //   "Condition": {
        //     "StringEquals": {
        //       "aws:SourceAccount": `${config.aws_account_id}`
        //     }
        //   },
        //   "Resource": [
        //     `${lambdaArn}:*`,
        //     `${lambdaArn}`
        //   ]
        // }
      ]
    }
    const inputP = { // CreatePolicyRequest
      PolicyName: `Amazon-EventBridge-Scheduler-Execution-Policy-${lambdaLongName}`,
      PolicyDocument: JSON.stringify(policyStatement),
      Description: `Scheduler Execution policy for ${lambdaLongName}`,
    };
    const commandP = new CreatePolicyCommand(inputP);
    return iamClient.send(commandP).then(policy => {
      console.log('policy:', policy)
      return policy.Policy
    }).then(policy => {
      const inputA = { // AttachRolePolicyRequest
        RoleName: role.RoleName,
        PolicyArn: policy.Arn
      };
      const command = new AttachRolePolicyCommand(inputA);
      return iamClient.send(command).then(attach => {
        console.log('attach:', attach)
        return attach
      }).then(_attach => {
        const schedulerClient = new SchedulerClient(initial)
        // create scheduler group
        const input = { // CreateScheduleGroupInput
          Name: SCHEDULER_GROUP,
        };
        const command = new CreateScheduleGroupCommand(input);
        return schedulerClient.send(command).then(group => {
          console.log('group:', group)
          return group.Group
        }).catch (err => {
          console.error('scheduler group exists')
        }).finally(() => {
          // create schedule
          const inputS = { // CreateScheduleInput
            Name: `Schedule-${lambdaLongName}`,
            GroupName: SCHEDULER_GROUP,
            ScheduleExpression: scheduleExpression,
            Description: description,
            ScheduleExpressionTimezone: TIMEZONE,
            Target: { // Target
              Arn: lambdaArn,
              RoleArn: role.Arn,
              Input: JSON.stringify(params),
            },
            FlexibleTimeWindow: {
              Mode: FlexibleTimeWindowMode.OFF,
            },
          }
          console.log(JSON.stringify(inputS))
          const command = new CreateScheduleCommand(inputS)
          return schedulerClient.send(command)
        }).then(schedule => {
          console.log('schedule:', schedule)
          return schedule
        })
      })
    })
  })

Observed Behavior

ValidationException: The execution role you provide must allow AWS EventBridge Scheduler to assume the role.
    at de_ValidationExceptionRes (/home/dflesner/tune/code/git/codeadx/dan/podadx-aws/node_modules/@aws-sdk/client-scheduler/dist-cjs/index.js:837:21)
    at de_CommandError (/home/dflesner/tune/code/git/codeadx/dan/podadx-aws/node_modules/@aws-sdk/client-scheduler/dist-cjs/index.js:754:19)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async /home/dflesner/tune/code/git/codeadx/dan/podadx-aws/node_modules/@aws-sdk/client-scheduler/node_modules/@smithy/middleware-serde/dist-cjs/index.js:35:20
    at async /home/dflesner/tune/code/git/codeadx/dan/podadx-aws/node_modules/@aws-sdk/client-scheduler/node_modules/@smithy/core/dist-cjs/index.js:165:18
    at async /home/dflesner/tune/code/git/codeadx/dan/podadx-aws/node_modules/@aws-sdk/client-scheduler/node_modules/@smithy/middleware-retry/dist-cjs/index.js:320:38
    at async /home/dflesner/tune/code/git/codeadx/dan/podadx-aws/node_modules/@aws-sdk/client-scheduler/node_modules/@aws-sdk/middleware-logger/dist-cjs/index.js:34:22 {
  '$fault': 'client',
  '$metadata': {
    httpStatusCode: 400,
    requestId: '40ae0f9d-b014-4448-9b87-ed00403e09c6',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  }
}

Expected Behavior

succeed

Possible Solution

Move the validation check to the correct Policy

Additional Information/Context

No response

@defmtog defmtog added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Sep 19, 2024
@zshzbh zshzbh self-assigned this Sep 19, 2024
@zshzbh
Copy link
Contributor

zshzbh commented Sep 23, 2024

Hey @defmtog ,

Thanks for your feedback! After deep #diving into this issue, I think the possible root cause could be assumePolicy object.

In this EventBridge Scheduler - Setting up the execution role doc

The role policy should look like this :

Screenshot 2024-09-23 at 10 09 49 AM

Could you please update the trusted policy to the json posted below?

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

Please let me know if that works.

I will post my reproduction steps later.

Thanks!
Maggie

@zshzbh
Copy link
Contributor

zshzbh commented Sep 23, 2024

Posting my reproduction steps for reference -

Step 1 - Create IAM client

const iamClient = new  IAMClient()

Step 2 - Create Assume Policy and send the CreateRoleCommand

  const assumePolicy = {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Principal": {
          "Service": "scheduler.amazonaws.com"
        },
        "Action": "sts:AssumeRole",
        "Condition": {
          "StringEquals": {
            "aws:SourceAccount": "*" // I used your code at this time
          }
        }
      }
    ]
  }
  console.log(JSON.stringify(assumePolicy))
  const inputR = { // CreateRoleRequest
    RoleName: `Amazon_Testing_Role`,
    AssumeRolePolicyDocument: JSON.stringify(assumePolicy),
    Description: `Execution role for testing`
  }
  const commandR = new CreateRoleCommand(inputR)
	console.log(commandR);

Step 3 - Create policy statemen, send CreatePolicyCommand and attach policy

const policyStatement = {
	"Version": "2012-10-17",
	"Statement": [
	  {
		"Effect": "Allow",
		"Action": [
		  "lambda:InvokeFunction"
		],
		"Resource": "*"
	  }

	]
  }
 
  const input = { // CreatePolicyRequest
	PolicyName: "amazon_testing_policy", // required
	// Path: "STRING_VALUE",
	PolicyDocument:  JSON.stringify(policyStatement), // required
	Description: "testing policy",
  };
  const commandP = new CreatePolicyCommand(input);
  const response = await iamClient.send(commandP);
  console.log(response)

// attach policy
  const inputA = { // AttachRolePolicyRequest
	RoleName: "Amazon_Testing_Role",
	PolicyArn: "arn:aws:iam::XXXXX:policy/amazon_testing_policy"
  };
  const commandAttacth = new AttachRolePolicyCommand(inputA);
  const res = await iamClient.send(commandAttacth);
  console.log(res);

Step 4 - Create schedulerClient and send CreateScheduleGroupCommand

const schedulerClient = new SchedulerClient()



  // create scheduler group
  const input = { // CreateScheduleGroupInput
	Name: "scheduler_testing",
  };
  const command = new CreateScheduleGroupCommand(input);
  const res = await schedulerClient.send(command);
  console.log(res)

Step 5 -Create Schedule and send CreateScheduleCommand

      // create schedule
	  const inputS = { // CreateScheduleInput
		Name: `Schedule-testing`,
		GroupName: "SCHEDULER_GROUP",
		ScheduleExpression:"rate(5 minutes)",
		Description: "testing",
		ScheduleExpressionTimezone: "America/New_York",
		Target: { // Target
		  Arn: "arn:aws:lambda:us-west-2:XXXX:function:myKinesis",
		  RoleArn: "arn:aws:iam::XXX:role/Amazon_Testing_Role",
		//   Input: JSON.stringify(params),
		},
		FlexibleTimeWindow: {
		  Mode: FlexibleTimeWindowMode.OFF,
		},
	  }
	  console.log(JSON.stringify(inputS))
	  const command = new CreateScheduleCommand(inputS)
	  const res = schedulerClient.send(command);
	  console.log(res)

Then I got this error after executing step 5 code -

ValidationException: The execution role you provide must allow AWS EventBridge Scheduler to assume the role.

Step 6 - Manually update the trust relationships

Screenshot 2024-09-23 at 10 06 13 AM

Step 6 - Run step 5's code again

And received a successfully message -

{"Name":"Schedule-testing_2","GroupName":"scheduler_testing_1","ScheduleExpression":"rate(6 minutes)","Description":"testing_1","ScheduleExpressionTimezone":"America/New_York","Target":{"Arn":"arn:aws:lambda:us-west-2:XXXX:function:myKinesis","RoleArn":"arn:aws:iam::XXXX:role/Amazon_Testing_Role"},"FlexibleTimeWindow":{"Mode":"OFF"}}
{
  '$metadata': {
    httpStatusCode: 200,
    requestId: 'c1ac28b6-e320-43aa-a21e-XXXXXX',
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  ScheduleArn: 'arn:aws:scheduler:us-west-2:XXXX:schedule/scheduler_testing_1/Schedule-testing_2'

Step 7 - Check on AWS console
Screenshot 2024-09-23 at 10 07 58 AM
The policy has been successfully created.

@defmtog
Copy link
Author

defmtog commented Sep 23, 2024 via email

@zshzbh
Copy link
Contributor

zshzbh commented Sep 23, 2024

Hey @defmtog ,

I just updated my response. Could you please try to change the trust policy to

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

?

@zshzbh
Copy link
Contributor

zshzbh commented Sep 23, 2024

Putting the IAM role arn to "aws:SourceAccount" property worked once for me. But this workaround fails afterwards.

By changing the trust policy to the json in my updated response, it works multiple times. I consider this would be the stable workarounds towards this issue.

So I updated the response. Please let me know if that works for you!

Thanks!
Maggie

@zshzbh zshzbh added response-requested Waiting on additional info and feedback. Will move to \"closing-soon\" in 7 days. p2 This is a standard priority issue and removed needs-triage This issue or PR still needs to be triaged. labels Sep 23, 2024
@defmtog
Copy link
Author

defmtog commented Sep 23, 2024 via email

@defmtog
Copy link
Author

defmtog commented Sep 23, 2024 via email

@zshzbh
Copy link
Contributor

zshzbh commented Sep 23, 2024

Did you update the scheduler's name?

If you are sending the duplicated name, it will throw 409 error.

@defmtog
Copy link
Author

defmtog commented Sep 24, 2024 via email

@zshzbh
Copy link
Contributor

zshzbh commented Sep 24, 2024

Could you please take a screenshot of your current trust relationship and permission?

Thanks!~
Maggie

@defmtog
Copy link
Author

defmtog commented Sep 24, 2024

trust_relationship
permissions

@zshzbh
Copy link
Contributor

zshzbh commented Sep 24, 2024

Could you please try to change the permission policy to the following json content?

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": "*"
        }
    ]
}

@defmtog
Copy link
Author

defmtog commented Sep 24, 2024

nope, still throws: ValidationException: The execution role you provide must allow AWS EventBridge Scheduler to assume the role.

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to \"closing-soon\" in 7 days. label Sep 27, 2024
@zshzbh
Copy link
Contributor

zshzbh commented Oct 2, 2024

I will check with the AWS EventBridge Scheduler service team and get back to you once we have an update. To unblock your work, please use what is working for you now.

Thanks!
Maggie

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. p2 This is a standard priority issue
Projects
None yet
Development

No branches or pull requests

2 participants