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

@aws-cdk/aws-events: Can't create EventBridge Rule for bus in different region #26032

Open
morcs opened this issue Jun 18, 2023 · 15 comments
Open
Labels
@aws-cdk/aws-events Related to CloudWatch Events bug This issue is a bug. effort/medium Medium work item – several days of effort needs-cfn This issue is waiting on changes to CloudFormation before it can be addressed. p2

Comments

@morcs
Copy link

morcs commented Jun 18, 2023

Describe the bug

I want to add a rule on an Event Bus in a different account and region. If I create a new Rule, the CDK seems to ignore the region in the event bus' ARN and uses the region of the current app instead.

Expected Behavior

I expect the CDK to try to create the rule on the event bus specified. (in this case the event bus ARN is arn:aws:events:eu-west-2:XXXXXXXXXXXX:event-bus/my-event-bus)

Current Behavior

I receive the following error (N.b. The CDK app is deployed in the us-east-1 region).

Error: The stack named XAcctDestinationBusStack failed to deploy: UPDATE_ROLLBACK_COMPLETE: User: arn:aws:sts::YYYYYYYYYYYY:assumed-role/cdk-hnb659fds-cfn-exec-role-YYYYYYYYYYYY-us-east-1/AWSCloudFormation is not authorized to perform: events:PutRule on resource: arn:aws:events:us-east-1:XXXXXXXXXXXX:rule/my-event-bus/XAcctDestinationBusStack-forwardEventsFromSourceBu-SI90TXUR6U6F because no resource-based policy allows the events:PutRule action (Service: AmazonCloudWatchEvents; Status Code: 400; Error Code: AccessDeniedException;

Note that the region in the ARN has been changed to the app region us-east-1, which is why it fails.

Reproduction Steps

const sourceBusArn =
  "arn:aws:events:eu-west-2:XXXXXXXXXXXX:event-bus/my-event-bus";


export class XAcctDestinationBusStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const bus = new events.EventBus(this, "bus");

    const sourceBus = events.EventBus.fromEventBusAttributes(
      this,
      "sourceBus",
      {
        eventBusArn: sourceBusArn,
        eventBusName: sourceBusArn,
        eventBusPolicy: "",
      }
    );

    new events.Rule(this, "forwardEventsFromSourceBus", {
      eventBus: sourceBus,
      eventPattern: { source: ["*"] },
      targets: [new targets.EventBus(bus)],
    });
  }
}

Possible Solution

I've looked into the source code and the Rule class seems to construct a new CfnRule, passing in the ARN as eventBusName, I'm not sure how to find the source of CfnRule to see what it's doing with the region.

Additional Information/Context

No response

CDK CLI Version

2.84.0 (build f7c792f)

Framework Version

No response

Node.js Version

16.20.0

OS

MacOS Ventura 13.4

Language

Typescript

Language Version

No response

Other information

No response

@morcs morcs added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jun 18, 2023
@github-actions github-actions bot added the @aws-cdk/aws-events Related to CloudWatch Events label Jun 18, 2023
@pahud
Copy link
Contributor

pahud commented Jun 19, 2023

Looks like AWS::Events::Rule only accept EventBusName rather than the full ARN, which means it seems implicitly assume the same region. If that is the case, I am afraid cross-region might not be supported in CFN?

eventBusName: props.eventBus && props.eventBus.eventBusName,

@pahud pahud added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. p2 effort/medium Medium work item – several days of effort and removed needs-triage This issue or PR still needs to be triaged. labels Jun 19, 2023
@peterwoodworth
Copy link
Contributor

The API requires the name too instead of ARN. Is this supported by the service even?

@peterwoodworth peterwoodworth added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. labels Jun 19, 2023
@morcs
Copy link
Author

morcs commented Jun 20, 2023

The documentation for eventBusName states: "The name or ARN of the event bus associated with the rule." So it's confusingly named but should be able to (and actually will) accept an ARN.

N.b. You can tell that it reads more than just he name because it gets the account ID from the ARN correctly, and I've successfully been able to do this when the external event bus is in the same region as the current stack but in a different account.

I should add the reason I want to do this...we're implementing a separate "DevOps bus" account as per this article: https:/aws-samples/amazon-eventbridge-resource-policy-samples/blob/main/patterns/README.md (I guess the article's author has all their services in the same regions so didn't hit this issue).

In this pattern the rules are created on the bus in the central account by the subscriber accounts, leaving the central bus account cleanly separated from that logic.

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Jun 20, 2023
@peterwoodworth
Copy link
Contributor

Ah, thanks for clarifying this.

I tested this with an escape hatch, and it resulted in an error. Code:

    const bus = new events.EventBus(this, "bus");

    const sourceBus = events.EventBus.fromEventBusAttributes(
      this,
      "sourceBus",
      {
        eventBusArn: 'arn:aws:events:us-west-2:123456789012:event-bus/DefaultEventBus',
        eventBusName: 'default',
        eventBusPolicy: "",
      }
    );

    const rule = new events.Rule(this, "forwardEventsFromSourceBus", {
      eventBus: sourceBus,
      eventPattern: { source: ["*"] },
      targets: [new targets.EventBus(bus)],
    });

    (rule.node.defaultChild as events.CfnRule).addPropertyOverride('EventBusName', 'arn:aws:events:us-west-2:123456789012:event-bus/default')

Error:

Cross-region api call is not allowed. (Service: AmazonCloudWatchEvents; Status Code: 400; Error Code: ValidationException;

It could be a bug with CloudFormation, or maybe I don't have my permissions set up correctly. Are you able to try testing this escape hatch method to ensure the template has the arn instead of the name?

@peterwoodworth peterwoodworth added the needs-cfn This issue is waiting on changes to CloudFormation before it can be addressed. label Jun 20, 2023
@morcs
Copy link
Author

morcs commented Jun 20, 2023

Thanks for this!

I've tried adding the addPropertyOverride to my rule as you've shown here and I get the same error as before, and can see that the region is still coming through wrong. Hopefully that's useful! 😅

@peterwoodworth
Copy link
Contributor

peterwoodworth commented Jun 20, 2023

Might be a bug on CloudFormation's end, let me report to to them. I'll provide an update here when one becomes available

Actually, I can't find any evidence that this is supported by the service. I cannot seem to create a Rule with a cross region event bus in the console. If you have any evidence to the contrary, let me know

@peterwoodworth peterwoodworth added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Jun 20, 2023
@morcs
Copy link
Author

morcs commented Jun 21, 2023

It's an odd one - I think there's no way to create it in the console UI but I have successfully created cross-account rules via the CDK, it's just they only work when both stacks are in the same region due to this strange behaviour where it ignores the region in the ARN (but respects the account ID).

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Jun 21, 2023
@peterwoodworth
Copy link
Contributor

If that's the case then I doubt the service supports a Rule receiving events from a cross region event bus. I can only find documentation on targeting a bus in a different account/region, which is of course ok. Is there any reason you want to have a Rule receiving events from a bus in another region, instead of creating a Rule in that region which targets a bus in another region?

@peterwoodworth peterwoodworth added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Jun 21, 2023
@morcs
Copy link
Author

morcs commented Jun 22, 2023

Yeah I would say the main reason is to keep the logic about which events the subscriber is interested in with the subscriber, for cleaner separation of concerns, where the central/global bus account needn't be concerned with it. This is based on this article/reInvent talk (with GitHub repo) where the rules are specified in the subscriber stacks, despite the bus they're attached to being in a separate account. I'm guessing in this case all of the stacks happened to be in the same region across all accounts so the issue didn't arise.

https://markn.ca/2020/building-event-driven-applications-with-amazon-eventbridge/

@morcs
Copy link
Author

morcs commented Jun 22, 2023

I've contacted the author who confirms that is the intention 🙂

https://twitter.com/sliedigaws/status/1671782883546259456?s=20

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Jun 22, 2023
@kiwi-33
Copy link

kiwi-33 commented Jul 20, 2023

Hit this issue while following the blog https://aws.amazon.com/blogs/compute/simplifying-cross-account-access-with-amazon-eventbridge-resource-policies/

Shame that CDK requires you to use an IEventBus as the EventBus for the Rule, but only renders the name in the CFN template.

The escape hatch works for me because it's the same region, but even a quick explanation in the docstrings would have helped a lot.

@peterwoodworth
Copy link
Contributor

@morcs that intention makes sense 🙂 Sorry this fell off my radar. Do you think I should reach out to events / CloudFormation about this? It still seems to me like this is at least blocked for CDK through CloudFormation

@kiwi-33 I'm not sure you ran into the same problem that has been described in this thread. Could you explain what the issue with using IEventBus is? It's core to CDK's design that we take in constructs as input rather than individual values

@kiwi-33
Copy link

kiwi-33 commented Jul 25, 2023

Hi @peterwoodworth - we are creating an Event Rule on a Bus in a different account.

const rule = new Rule(this, 'ForwardingRule', {
    eventBus: centralEventBus, // This is in a different account from the Stack being deployed
    targets: [new cdk.aws_events_targets.EventBus(eventBus)],
    eventPattern: { account: 123456789012 },
});

In the CF template, the full ARN is not rendered, it is just the Event Bus name. So we also have to add:

(rule.node.defaultChild as CfnRule).eventBusName = centralEventBus.eventBusArn;

If I read correctly - https:/aws/aws-cdk/blob/main/packages/aws-cdk-lib/aws-events/lib/rule.ts#L114 this should be setting the eventBusArn, not eventBusName.

@morcs
Copy link
Author

morcs commented Jul 25, 2023

@peterwoodworth I agree it seems to be an issue at the CloudFormation level, would be good to see what they say 🙂👍

@peterwoodworth
Copy link
Contributor

To post an update here, I have reported this internally and will provide updates when I have them (P99178026)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-events Related to CloudWatch Events bug This issue is a bug. effort/medium Medium work item – several days of effort needs-cfn This issue is waiting on changes to CloudFormation before it can be addressed. p2
Projects
None yet
Development

No branches or pull requests

4 participants