EventBus
caution
This is the SST v0.x Constructs doc. SST v1 is now released. If you are using v1, see the v1 Constructs doc. If you are looking to upgrade to v1, check out the migration steps.
The EventBus
construct is a higher level CDK construct that makes it easy to create an EventBridge Event Bus. You can create a bus that has a list of rules and targets. And you can publish messages to it from any part of your serverless app.
You can have two types of targets; Function targets (with a Lambda function) or Queue targets (with an SQS queue). See the examples for more details.
Initializer
new EventBus(scope: Construct, id: string, props: EventBusProps)
Parameters
- scope
Construct
- id
string
- props
EventBusProps
Examples
The EventBus
construct is designed to make it easy to get started with, while allowing for a way to fully configure it as well. Let's look at how, through a couple of examples.
Using the minimal config
import { EventBus } from "@serverless-stack/resources";
new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
Note that, rule1
here is simply a key to identify the rule.
Adding rules
Add rules after the EventBus has been created.
const bus = new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
bus.addRules(this, {
rule2: {
eventPattern: { source: ["myevent"] },
targets: ["src/target3.main", "src/target4.main"],
},
});
Lazily adding rules
Create an empty EventBus construct and lazily add the rules.
const bus = new EventBus(this, "Bus");
bus.addRules(this, {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
});
Configuring Function targets
Specifying the function path
You can directly pass in the path to the Function
.
new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main"],
},
},
});
Specifying function props
If you wanted to configure each Lambda function separately, you can pass in the EventBusFunctionTargetProps
.
new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: [
{
function: {
srcPath: "src/",
handler: "target1.main",
environment: { tableName: table.tableName },
permissions: [table],
},
},
],
},
},
});
Specifying function props for all targets
You can extend the minimal config, to set some function props and have them apply to all the rules.
new EventBus(this, "Bus", {
defaultFunctionProps: {
timeout: 20,
environment: { tableName: table.tableName },
permissions: [table],
},
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
Note that, you can set the defaultFunctionProps
while using the function
per target. The function
will just override the defaultFunctionProps
. Except for the environment
, the layers
, and the permissions
properties, that will be merged.
new EventBus(this, "Bus", {
defaultFunctionProps: {
timeout: 20,
environment: { tableName: table.tableName },
permissions: [table],
},
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: [
{
function: {
handler: "src/target1.main",
timeout: 10,
environment: { bucketName: bucket.bucketName },
permissions: [bucket],
},
},
"src/target2.main",
],
},
},
});
So in the above example, the target1
function doesn't use the timeout
that is set in the defaultFunctionProps
. It'll instead use the one that is defined in the function definition (10 seconds
). And the function will have both the tableName
and the bucketName
environment variables set; as well as permissions to both the table
and the bucket
.
Configuring the target
Configure the internally created CDK Target
.
import { RuleTargetInput } from 'aws-cdk-lib/aws-events';
new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: [
{
function: "src/target1.main",
targetProps: {
retryAttempts: 20,
message: RuleTargetInput.fromEventPath('$.detail'),
},
},
],
},
},
});
In the example above, the function is invoked with the contents of the detail
property on the event, instead of the envelope - i.e. the original payload put onto the EventBus.
Attaching permissions for all targets
Allow all the targets in the entire EventBus to access S3.
const bus = new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
bus.attachPermissions(["s3"]);
Attaching permissions for a specific target
Allow one of the targets to access S3.
const bus = new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
bus.attachPermissionsToTarget("rule1", 0, ["s3"]);
Here we are referring to the rule using the rule key, rule1
.
Configuring Queue targets
Specifying the Queue directly
You can directly pass in a Queue
.
const myQueue = new Queue(this, "MyQueue");
new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: [myQueue],
},
},
});
Configuring the target
Configure the internally created CDK Target
.
new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: [
{
queue: myQueue,
targetProps: {
messageGroupId: "group1",
},
},
],
},
},
});
Configuring the EventBus
Configure the internally created CDK EventBus
instance.
new EventBus(this, "Bus", {
eventBridgeEventBus: {
eventBusName: "MyEventBus",
},
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
Configuring the Rule
Configure the internally created CDK Rule
instance.
new EventBus(this, "Bus", {
rules: {
rule1: {
ruleName: "MyRule",
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
Importing an existing EventBus
Override the internally created CDK EventBus
instance.
import * as events from "aws-cdk-lib/aws-events";
new EventBus(this, "Bus", {
eventBridgeEventBus: events.EventBus.fromEventBusArn(
this, "ImportedBus", eventBusArn
),
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
Receiving AWS events
When an AWS service in your account emits an event, it goes to your account’s default event bus.
import * as events from "aws-cdk-lib/aws-events";
new EventBus(this, "Bus", {
eventBridgeEventBus: events.EventBus.fromEventBusName(
this, "ImportedBus", "default"
),
rules: {
rule1: {
eventPattern: { source: ["aws.codebuild"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
Sharing an EventBus across stacks
You can create the EventBus construct in one stack, and add rules in other stacks. To do this, expose the EventBus as a class property.
- JavaScript
- TypeScript
import { EventBus, Stack } from "@serverless-stack/resources";
export class MainStack extends Stack {
constructor(scope, id, props) {
super(scope, id, props);
this.bus = new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
}
}
import { EventBus, App, Stack, StackProps } from "@serverless-stack/resources";
export class MainStack extends Stack {
public readonly bus: EventBus;
constructor(scope: App, id: string, props?: StackProps) {
super(scope, id, props);
this.bus = new EventBus(this, "Bus", {
rules: {
rule1: {
eventPattern: { source: ["myevent"] },
targets: ["src/target1.main", "src/target2.main"],
},
},
});
}
}
Then pass the EventBus to a different stack. Behind the scenes, the EventBus Arn is exported as an output of the MainStack
, and imported to AnotherStack
.
- JavaScript
- TypeScript
const mainStack = new MainStack(app, "main");
new AnotherStack(app, "another", { bus: mainStack.bus });
const mainStack = new MainStack(app, "main");
new AnotherStack(app, "another", { bus: mainStack.bus });
Finally, call addRules
. Note that the AWS resources for the added routes will be created in AnotherStack
.
- JavaScript
- TypeScript
import { Stack } from "@serverless-stack/resources";
export class AnotherStack extends Stack {
constructor(scope, id, props) {
super(scope, id, props);
props.bus.addRules(this, {
rule2: {
targets: ["src/target3.main", "src/target4.main"],
},
});
}
}
import { EventBus, App, Stack, StackProps } from "@serverless-stack/resources";
interface AnotherStackProps extends StackProps {
readonly bus: EventBus;
}
export class AnotherStack extends Stack {
constructor(scope: App, id: string, props: AnotherStackProps) {
super(scope, id, props);
props.bus.addRules(this, {
rule2: {
targets: ["src/target3.main", "src/target4.main"],
},
});
}
}
Properties
An instance of EventBus
contains the following properties.
eventBusArn
Type: string
The ARN of the internally created CDK EventBus
instance.
eventBusName
Type: string
The name of the internally created CDK EventBus
instance.
eventBridgeEventBus
Type: cdk.aws-events.EventBus
The internally created CDK EventBus
instance.
Methods
An instance of EventBus
contains the following methods.
addRules
addRules(scope: cdk.Construct, rules: { [key: string]: EventBusCdkRuleProps })
Parameters
- scope
cdk.Construct
- rules
{ [key: string]: EventBusCdkRuleProps }
An associative array where the key
is a name to identify the rule and the value is the EventBusCdkRuleProps
.
attachPermissions
attachPermissions(permissions: Permissions)
Parameters
- permissions
Permissions
Attaches the given list of permissions to all the targets in all the rules. This allows the functions to access other AWS resources.
Internally calls Function.attachPermissions
.
attachPermissionsToTarget
attachPermissionsToTarget(ruleKey: string, targetIndex: number, permissions: Permissions)
Parameters
ruleKey
string
targetIndex
number
permissions
Permissions
Attaches the given list of permissions to a specific target of a rule. This allows that function to access other AWS resources.
Internally calls Function.attachPermissions
.
EventBusProps
rules?
Type : { [key: string]: EventBusCdkRuleProps }
, defaults to {}
The rules for this EventBus. Takes an associative array, where the key
is a name to identify the rule and the value is the EventBusCdkRuleProps
.
eventBridgeEventBus?
Type : cdk.aws-events.EventBusProps | cdk.aws-events.EventBus
Pass in a cdk.aws-events.EventBus
value to override the default settings this construct uses to create the CDK EventBus
internally.
Or, pass in an instance of the CDK cdk.aws-events.EventBus
. SST will use the provided CDK EventBus
instead of creating one internally.
defaultFunctionProps?
Type : FunctionProps
, defaults to {}
The default function props to be applied to all the Lambda functions in the targets. If the function
is specified for a target, these default values are overridden. Except for the environment
, the layers
, and the permissions
properties, these will be merged.
EventBusFunctionTargetProps
function
Type : FunctionDefinition
The function definition used to create the function for this target.
targetProps?
Type : cdk.aws-events-targets.LambdaFunctionProps
, defaults to undefined
Or optionally pass in a CDK LambdaFunctionProps
. This allows you to override the default settings this construct uses internally to create the target.
EventBusQueueTargetProps
queue
Type : Queue
The Queue
construct that'll be added as a target to the bus.
targetProps?
Type : cdk.aws-events-targets.SqsQueueProps
, defaults to undefined
Or optionally pass in the CDK SqsQueueProps
. This allows you to override the default settings this construct uses internally to create the target.
EventBusCdkRuleProps
EventBusCdkRuleProps
extends cdk.aws-events.RuleProps
with the following exceptions.
targets
Type : (FunctionDefinition | EventBusFunctionTargetProps | Queue | EventBusQueueTargetProps)[]
A list of FunctionDefinition
, EventBusFunctionTargetProps
, Queue
, or EventBusQueueTargetProps
objects that'll be used to add the targets for the bus.
Use FunctionDefinition
or EventBusFunctionTargetProps
to add a Lambda function target.
Or, use Queue
or EventBusQueueTargetProps
to add a Queue target.