Skip to content

Commit

Permalink
feat(aws-events-targets) external event bus event target
Browse files Browse the repository at this point in the history
  • Loading branch information
alanraison committed Feb 8, 2021
1 parent 6de792c commit a598ba6
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-events-targets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Currently supported are:
* Put a record to a Kinesis stream
* Log an event into a LogGroup
* Put a record to a Kinesis Data Firehose stream
* Put an event on an EventBridge bus

See the README of the `@aws-cdk/aws-events` library for more information on
EventBridge.
Expand Down
52 changes: 52 additions & 0 deletions packages/@aws-cdk/aws-events-targets/lib/event-bus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as events from '@aws-cdk/aws-events';
import * as iam from '@aws-cdk/aws-iam';
import { singletonEventRole } from './util';

/**
* Configuration properties of an Event Bus event
*/
export interface EventBusProps {
/**
* The target event bus
*/
readonly eventBus: events.IEventBus;

/**
* Role to be used to publish the event
*
* @default a new role is created.
*/
readonly role?: iam.IRole;
}

/**
* Notify an existing Event Bus of an event
*/
export class EventBus implements events.IRuleTarget {
private readonly eventBus: events.IEventBus;
private readonly role?: iam.IRole;

constructor(props: EventBusProps) {
this.eventBus = props.eventBus;
this.role = props.role;
}

bind(rule: events.IRule, id?: string): events.RuleTargetConfig {
if (this.role) {
this.role.addToPrincipalPolicy(this.putEventStatement());
}
const role = this.role ?? singletonEventRole(rule, [this.putEventStatement()]);
return {
id: id ? id : '',
arn: this.eventBus.eventBusArn,
role,
};
}

private putEventStatement() {
return new iam.PolicyStatement({
actions: ['events:PutEvents'],
resources: [this.eventBus.eventBusArn],
});
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-events-targets/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './aws-api';
export * from './lambda';
export * from './ecs-task-properties';
export * from './ecs-task';
export * from './event-bus';
export * from './state-machine';
export * from './kinesis-stream';
export * from './log-group';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import '@aws-cdk/assert/jest';
import * as events from '@aws-cdk/aws-events';
import * as iam from '@aws-cdk/aws-iam';
import { Stack } from '@aws-cdk/core';
import * as targets from '../../lib';

test('Use EventBus as an event rule target', () => {
const stack = new Stack();
const rule = new events.Rule(stack, 'Rule', {
schedule: events.Schedule.expression('rate(1 min)'),
});

rule.addTarget(new targets.EventBus({
eventBus: events.EventBus.fromEventBusArn(
stack,
'External',
'arn:aws:events:us-east-1:111111111111:default'
),
}));

expect(stack).toHaveResource('AWS::Events::Rule', {
Targets: [
{
Arn: 'arn:aws:events:us-east-1:111111111111:default',
Id: 'Target0',
RoleArn: {
'Fn::GetAtt': [
'RuleEventsRoleC51A4248',
'Arn',
],
},
},
],
});
expect(stack).toHaveResource('AWS::IAM::Policy', {
PolicyDocument: {
Statement: [{
Effect: 'Allow',
Action: 'events:PutEvents',
Resource: 'arn:aws:events:us-east-1:111111111111:default',
}],
Version: '2012-10-17',
},
Roles: [{
Ref: 'RuleEventsRoleC51A4248',
}],
});
});

test('with supplied role', () => {
const stack = new Stack();
const rule = new events.Rule(stack, 'Rule', {
schedule: events.Schedule.expression('rate(1 min)'),
});
const role = new iam.Role(stack, 'Role', {
assumedBy: new iam.ServicePrincipal('events.amazonaws.com'),
roleName: 'GivenRole',
});

rule.addTarget(new targets.EventBus({
eventBus: events.EventBus.fromEventBusArn(
stack,
'External',
'arn:aws:events:us-east-1:123456789012:default'
),
role,
}));

expect(stack).toHaveResource('AWS::Events::Rule', {
Targets: [{
Arn: 'arn:aws:events:us-east-1:123456789012:default',
Id: 'Target0',
RoleArn: {
'Fn::GetAtt': [
'Role1ABCC5F0',
'Arn',
],
},
}],
});
expect(stack).toHaveResource('AWS::IAM::Policy', {
PolicyDocument: {
Statement: [{
Effect: 'Allow',
Action: 'events:PutEvents',
Resource: 'arn:aws:events:us-east-1:123456789012:default',
}],
Version: '2012-10-17',
},
Roles: [{
Ref: 'Role1ABCC5F0',
}],
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"Resources": {
"Rule4C995B7F": {
"Type": "AWS::Events::Rule",
"Properties": {
"ScheduleExpression": "rate(1 minute)",
"State": "ENABLED",
"Targets": [
{
"Arn": {
"Fn::Join": [
"",
[
"arn:aws:events:",
{
"Ref": "AWS::Region"
},
":999999999999:event-bus/test-bus"
]
]
},
"Id": "Target0",
"RoleArn": {
"Fn::GetAtt": [
"RuleEventsRoleC51A4248",
"Arn"
]
}
}
]
}
},
"RuleEventsRoleC51A4248": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
}
}
],
"Version": "2012-10-17"
}
}
},
"RuleEventsRoleDefaultPolicy0510525D": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "events:PutEvents",
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:aws:events:",
{
"Ref": "AWS::Region"
},
":999999999999:event-bus/test-bus"
]
]
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "RuleEventsRoleDefaultPolicy0510525D",
"Roles": [
{
"Ref": "RuleEventsRoleC51A4248"
}
]
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/// !cdk-integ pragma:ignore-assets
import * as events from '@aws-cdk/aws-events';
import * as cdk from '@aws-cdk/core';
import * as targets from '../../lib';

const app = new cdk.App();

class EventSourceStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);

const rule = new events.Rule(this, 'Rule', {
schedule: events.Schedule.expression('rate(1 minute)'),
});
rule.addTarget(new targets.EventBus({
eventBus: events.EventBus.fromEventBusArn(
this,
'External',
`arn:aws:events:${this.region}:999999999999:event-bus/test-bus`
),
}));
}
}

new EventSourceStack(app, 'event-source-stack');
app.synth();

0 comments on commit a598ba6

Please sign in to comment.