-
Notifications
You must be signed in to change notification settings - Fork 4k
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
feat(scheduler-targets): eventBridge putEvents target #27629
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { IScheduleTarget, ISchedule, ScheduleTargetInput, ScheduleTargetConfig } from '@aws-cdk/aws-scheduler-alpha'; | ||
import { Names } from 'aws-cdk-lib'; | ||
import * as events from 'aws-cdk-lib/aws-events'; | ||
import { IRole } from 'aws-cdk-lib/aws-iam'; | ||
import { ScheduleTargetBase, ScheduleTargetBaseProps } from './target'; | ||
import { sameEnvDimension } from './util'; | ||
|
||
/** | ||
* An entry to be sent to EventBridge | ||
* | ||
* @see https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutEventsRequestEntry.html | ||
*/ | ||
export interface EventBridgePutEventsEntry { | ||
/** | ||
* The event body | ||
* | ||
* Can either be provided as an object or as a JSON-serialized string | ||
* @example | ||
kaizencc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* | ||
* ScheduleTargetInput.fromText('{"instance-id": "i-1234567890abcdef0", "state": "terminated"}'); | ||
* ScheduleTargetInput.fromObject({ Message: 'Hello from a friendly event :)' }); | ||
*/ | ||
readonly detail: ScheduleTargetInput; | ||
|
||
/** | ||
* Used along with the source field to help identify the fields and values expected in the detail field | ||
* | ||
* For example, events by CloudTrail have detail type "AWS API Call via CloudTrail" | ||
* @see https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-events.html | ||
*/ | ||
readonly detailType: string; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can type this better than a readonly detailType: DetailType;
////
export class DetailType {
public static API_CALL_VIA_CLOUDTRAIL() {
return new DetailType('AWS API Call via CloudTrail');
}
public constructor (public readonly type: string) {}
} This way, we can a) give users an easy API to hit rather than getting the specific string correct ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do. There seems to be more, but not documented which Cant speak for others but our team uses only own detail types (e.g your point c). For context: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Introduced class There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Andddd I am now wavering on this suggestion. I still think it could be a good idea, but might be overengineered. I didn't see the nuance at first that most I think we should go back to using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just dropped my last commit, which effectively reverts the change. |
||
|
||
/** | ||
* The event bus the entry will be sent to. | ||
* | ||
*/ | ||
readonly eventBus: events.IEventBus; | ||
|
||
/** | ||
* The service or application that caused this event to be generated | ||
* | ||
* Example value: `com.example.service` | ||
* | ||
* @see https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-events.html | ||
*/ | ||
readonly source: string; | ||
} | ||
|
||
/** | ||
* Send an event to an AWS EventBridge by AWS EventBridge Scheduler. | ||
*/ | ||
export class EventBridgePutEvents extends ScheduleTargetBase implements IScheduleTarget { | ||
constructor( | ||
private readonly entry: EventBridgePutEventsEntry, | ||
private readonly props: ScheduleTargetBaseProps, | ||
) { | ||
super(props, entry.eventBus.eventBusArn); | ||
if (this.props.input) { | ||
throw new Error('ScheduleTargetBaseProps.input is not supported for EventBridgePutEvents. Please use entry.detail instead.'); | ||
} | ||
kaizencc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
protected addTargetActionToRole(schedule: ISchedule, role: IRole): void { | ||
const eventBus = this.entry.eventBus; | ||
const eventBusEnv = eventBus.env; | ||
if (!sameEnvDimension(eventBusEnv.region, schedule.env.region)) { | ||
throw new Error(`Cannot assign eventBus in region ${eventBusEnv.region} to the schedule ${Names.nodeUniqueId(schedule.node)} in region ${schedule.env.region}. Both the schedule and the eventBus must be in the same region.`); | ||
} | ||
|
||
if (!sameEnvDimension(eventBusEnv.account, schedule.env.account)) { | ||
throw new Error(`Cannot assign eventBus in account ${eventBusEnv.account} to the schedule ${Names.nodeUniqueId(schedule.node)} in account ${schedule.env.region}. Both the schedule and the eventBus must be in the same account.`); | ||
} | ||
|
||
if (this.props.role && !sameEnvDimension(this.props.role.env.account, eventBusEnv.account)) { | ||
throw new Error(`Cannot grant permission to execution role in account ${this.props.role.env.account} to invoke target ${Names.nodeUniqueId(eventBus.node)} in account ${eventBusEnv.account}. Both the target and the execution role must be in the same account.`); | ||
} | ||
|
||
eventBus.grantPutEventsTo(role); | ||
} | ||
|
||
protected bindBaseTargetConfig(_schedule: ISchedule): ScheduleTargetConfig { | ||
WtfJoke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return { | ||
...super.bindBaseTargetConfig(_schedule), | ||
input: this.entry.detail, | ||
eventBridgeParameters: { | ||
detailType: this.entry.detailType, | ||
source: this.entry.source, | ||
}, | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
export * from './codebuild-start-build'; | ||
export * from './event-bridge-put-events'; | ||
export * from './target'; | ||
export * from './lambda-invoke'; | ||
export * from './sns-publish'; | ||
export * from './sqs-send-message'; | ||
export * from './stepfunctions-start-execution'; | ||
export * from './target'; | ||
export * from './sqs-send-message'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
theres a section at the top of this readme that mentions what targets are available, can you put this and the stepfunctions one there please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StepFunction was already there. I've added eventbridge. Thanks for pointing this out