Skip to content

Commit 87b507f

Browse files
committed
added multiple consumers solution
1 parent b771111 commit 87b507f

File tree

6 files changed

+194
-89
lines changed

6 files changed

+194
-89
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"app": "npx ts-node --prefer-ts-exts index.ts",
3+
"context": {
4+
"appName": "eventbridge-mesh",
5+
"region": "us-east-1",
6+
"producerAccountId": "111111111111",
7+
"consumer1AccountId": "222222222222",
8+
"consumer2AccountId": "333333333333"
9+
}
10+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import * as cdk from 'aws-cdk-lib';
2+
import * as targets from 'aws-cdk-lib/aws-events-targets';
3+
import { EventBus, Rule } from 'aws-cdk-lib/aws-events';
4+
import { LogGroup } from 'aws-cdk-lib/aws-logs';
5+
import { CloudWatchLogGroup } from 'aws-cdk-lib/aws-events-targets';
6+
import { AccountPrincipal, Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam';
7+
import { Construct } from 'constructs';
8+
9+
export interface producerStackProps extends cdk.StackProps {
10+
readonly appName: string;
11+
readonly consumerAccounts: string[];
12+
}
13+
14+
export interface consumerStackProps extends cdk.StackProps {
15+
readonly appName: string;
16+
readonly consumerName: string;
17+
readonly producerAccountId: string;
18+
}
19+
20+
export class producerStack extends cdk.Stack {
21+
constructor(scope: Construct, id: string, props: producerStackProps) {
22+
super(scope, id, props);
23+
24+
// Create the EventBus
25+
const producerEventBus = new EventBus(this, `${props.appName}-producer-event-bus`);
26+
27+
props.consumerAccounts.forEach((consumerAccountId, index) => {
28+
// Create rule to forward events to consumer account
29+
const rule = new Rule(this, `${props.appName}-forward-to-consumer-${index + 1}-rule`, {
30+
eventBus: producerEventBus,
31+
eventPattern: {
32+
// Define your event pattern here
33+
source: ['com.myapp.events'],
34+
},
35+
});
36+
37+
// Add target to forward to consumer account's event bus
38+
rule.addTarget(new targets.EventBus(
39+
EventBus.fromEventBusArn(
40+
this,
41+
`${props.appName}-consumer-${index + 1}-event-bus`,
42+
`arn:aws:events:${cdk.Stack.of(this).region}:${consumerAccountId}:event-bus/default`
43+
)
44+
));
45+
});
46+
}
47+
}
48+
49+
export class consumerStack extends cdk.Stack {
50+
constructor(scope: Construct, id: string, props: consumerStackProps) {
51+
super(scope, id, props);
52+
53+
// Create or reference the consumer event bus
54+
const consumerEventBus = new EventBus(this, `${props.appName}-${props.consumerName}-event-bus`);
55+
56+
// Add policy to allow producer account to put events
57+
consumerEventBus.addToResourcePolicy(new PolicyStatement({
58+
sid: 'allowProducerAccount',
59+
effect: Effect.ALLOW,
60+
principals: [new AccountPrincipal(props.producerAccountId)],
61+
actions: ['events:PutEvents'],
62+
resources: [consumerEventBus.eventBusArn]
63+
}));
64+
65+
// Create consumer rules
66+
const consumerRule = new Rule(this, `${props.appName}-${props.consumerName}-rule`, {
67+
eventBus: consumerEventBus,
68+
eventPattern: {
69+
// Define more specific filtering here
70+
source: ['com.myapp.events'],
71+
detail: {
72+
type: ['specific-event-type']
73+
}
74+
}
75+
});
76+
77+
// Add target (e.g., CloudWatch)
78+
consumerRule.addTarget(new CloudWatchLogGroup(
79+
new LogGroup(this, `${props.appName}-${props.consumerName}-logs`)
80+
));
81+
}
82+
}
83+
84+
const app = new cdk.App();
85+
const appName = app.node.tryGetContext('appName');
86+
const region = app.node.tryGetContext('region');
87+
const producerAccountId = app.node.tryGetContext('producerAccountId');
88+
const consumer1AccountId = app.node.tryGetContext('consumer1AccountId');
89+
const consumer2AccountId = app.node.tryGetContext('consumer2AccountId');
90+
91+
new producerStack(app, `${appName}-producer-stack`, {
92+
env: {
93+
account: producerAccountId,
94+
region: region,
95+
},
96+
appName,
97+
consumerAccounts: [consumer1AccountId, consumer2AccountId],
98+
});
99+
100+
// Deploy consumer 1 stack
101+
new consumerStack(app, `${appName}-consumer1-stack`, {
102+
env: {
103+
account: consumer1AccountId,
104+
region: region,
105+
},
106+
appName,
107+
producerAccountId,
108+
consumerName: 'consumer1'
109+
});
110+
111+
// Deploy consumer 2 stack
112+
new consumerStack(app, `${appName}-consumer2-stack`, {
113+
env: {
114+
account: consumer2AccountId,
115+
region: region,
116+
},
117+
appName,
118+
producerAccountId,
119+
consumerName: 'consumer2'
120+
});
121+
122+
app.synth();
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "eventbridge-mesh",
3+
"version": "0.1.0",
4+
"scripts": {
5+
"build": "tsc",
6+
"watch": "tsc -w",
7+
"test": "jest",
8+
"cdk": "cdk"
9+
},
10+
"devDependencies": {
11+
"@types/jest": "^29.5.14",
12+
"@types/node": "22.7.9",
13+
"jest": "^29.7.0",
14+
"ts-jest": "^29.2.5",
15+
"aws-cdk": "2.1007.0",
16+
"ts-node": "^10.9.2",
17+
"typescript": "~5.6.3"
18+
},
19+
"dependencies": {
20+
"aws-cdk-lib": "2.186.0",
21+
"constructs": "^10.0.0"
22+
}
23+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2020",
4+
"module": "commonjs",
5+
"lib": [
6+
"es2020",
7+
"dom"
8+
],
9+
"declaration": true,
10+
"strict": true,
11+
"noImplicitAny": true,
12+
"strictNullChecks": true,
13+
"noImplicitThis": true,
14+
"alwaysStrict": true,
15+
"noUnusedLocals": false,
16+
"noUnusedParameters": false,
17+
"noImplicitReturns": true,
18+
"noFallthroughCasesInSwitch": false,
19+
"inlineSourceMap": true,
20+
"inlineSources": true,
21+
"experimentalDecorators": true,
22+
"strictPropertyInitialization": false,
23+
"typeRoots": [
24+
"./node_modules/@types"
25+
]
26+
},
27+
"exclude": [
28+
"node_modules",
29+
"cdk.out"
30+
]
31+
}
Lines changed: 4 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,9 @@
11
{
22
"app": "npx ts-node --prefer-ts-exts index.ts",
3-
"watch": {
4-
"include": [
5-
"**"
6-
],
7-
"exclude": [
8-
"README.md",
9-
"cdk*.json",
10-
"**/*.d.ts",
11-
"**/*.js",
12-
"tsconfig.json",
13-
"package*.json",
14-
"yarn.lock",
15-
"node_modules",
16-
"test"
17-
]
18-
},
193
"context": {
20-
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
21-
"@aws-cdk/core:checkSecretUsage": true,
22-
"@aws-cdk/core:target-partitions": [
23-
"aws",
24-
"aws-cn"
25-
],
26-
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
27-
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
28-
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
29-
"@aws-cdk/aws-iam:minimizePolicies": true,
30-
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
31-
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
32-
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
33-
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
34-
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
35-
"@aws-cdk/core:enablePartitionLiterals": true,
36-
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
37-
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
38-
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
39-
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
40-
"@aws-cdk/aws-route53-patters:useCertificate": true,
41-
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
42-
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
43-
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
44-
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
45-
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
46-
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
47-
"@aws-cdk/aws-redshift:columnId": true,
48-
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
49-
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
50-
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
51-
"@aws-cdk/aws-kms:aliasNameRef": true,
52-
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
53-
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
54-
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
55-
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
56-
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
57-
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
58-
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
59-
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
60-
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
61-
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
62-
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
63-
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
64-
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
65-
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
66-
"@aws-cdk/aws-eks:nodegroupNameAttribute": true,
67-
"@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
68-
"@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
69-
"@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
70-
"@aws-cdk/aws-s3:keepNotificationInImportedBucket": false,
71-
"@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": false,
72-
"@aws-cdk/aws-ecs:disableEcsImdsBlocking": true,
73-
"@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true,
74-
"@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true,
75-
"@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true,
76-
"@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true,
77-
"@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true,
78-
"@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true,
79-
"@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true,
80-
"@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true,
81-
"@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true,
82-
"@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": true,
83-
"@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true,
84-
"@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true,
85-
"@aws-cdk/core:enableAdditionalMetadataCollection": true,
86-
"@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": true,
87-
"@aws-cdk/aws-s3:setUniqueReplicationRoleName": true,
88-
"@aws-cdk/aws-events:requireEventBusPolicySid": true
4+
"appName": "eventbridge-mesh",
5+
"region": "us-east-1",
6+
"producerAccountId": "111111111111",
7+
"consumerAccountId": "222222222222"
898
}
909
}

typescript/eventbridge-mesh/single-consumer/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ export class producerStack extends cdk.Stack {
8484
}
8585

8686
const app = new cdk.App();
87-
const appName = 'eventbridge-mesh';
88-
const region = 'us-east-1';
89-
const producerAccountId = '123510061335';
90-
const consumerAccountId = '737719307477';
87+
const appName = app.node.tryGetContext('appName');
88+
const region = app.node.tryGetContext('region');
89+
const producerAccountId = app.node.tryGetContext('producerAccountId');
90+
const consumerAccountId = app.node.tryGetContext('consumer1AccountId');
9191

9292
new producerStack(app, `${appName}-producer-stack`, {
9393
env: {

0 commit comments

Comments
 (0)