I’m trying to create an EventBus, and want to add ...
# help
ö
I’m trying to create an EventBus, and want to add SNS topic as target. Can’t I do it with
sst.EventBus
construct? It seems like it only allows for lambda and SQS targets
So I want
eventBus
to put events into
snsTopic
Copy code
import { App, Stack, StackProps, EventBus, Topic } from "@serverless-stack/resources";

export class MainStack extends Stack {

      constructor(scope: App, id: string, props?: StackProps) {
            super(scope, id, props);


            const snsTopic = new Topic(this, "Topic", {
                  subscribers: ["src/sns/fallback/index.main"],
                  snsTopic: {
                        topicName: 'FallbackTopic',
                        displayName: 'Fallback'
                  },
            });

            const eventBus = new EventBus(this, id, {
                  eventBridgeEventBus: {
                        eventBusName: 'FallbackBus',
                  },
            })


            this.addOutputs({
                  EventBusName: eventBus.eventBusName,
                  SNSTopicName: snsTopic.topicName
            });
      }
}
Looking at the source code (
node_modules/@serverless-stack/resources/src/EventBus.ts
) I see that it is not possible to add anything other than Queue or Function as the target, though TypeScript already tells that. 🥲
o
You can try the raw Rule CDK construct and pass it
eventBus.eventBridgeEventBus
for now
ö
I see, I did this instead:
Copy code
import * as sst from '@serverless-stack/resources'
import * as events from '@aws-cdk/aws-events'
import * as targets from '@aws-cdk/aws-events-targets'

export class MainStack extends sst.Stack {

      constructor(scope: <http://sst.App|sst.App>, id: string, props?: sst.StackProps) {
            super(scope, id, props)
            const eventBus = new events.EventBus(this, id, {
                  eventBusName: 'FallbackBus'
            })
            const snsTopic = new sst.Topic(this, 'SNSTopic', {
                  snsTopic: {
                        topicName: 'FallbackTopic'
                  }
            })
            const snsTarget = new targets.SnsTopic(snsTopic.snsTopic)
            const fallbackRule = new events.Rule(this, 'FallbackRule', {
                  description: 'Put events to SNS Topic',
                  eventBus,
                  ruleName: 'FallbackRule',
                  targets: [snsTarget],
                  eventPattern: {
                        account: [scope.account],
                  }
            })
            
            const api = new sst.ApiGatewayV1Api(this, 'Api', {
                  routes: {
                        'POST /create-event': 'src/handlers/apiGateway/create-event/index.main'
                  }
            })
            this.addOutputs({
                  EventBusName: eventBus.eventBusName,
                  SNSTopicName: snsTopic.topicName,
                  RESTEndpoint: api.url
            })
      }
}
Not sure if I got it right, but will see
o
Ah ok yeah that should work - you’re using the raw CDK eventbus instead of the SST one - either will work, you just don’t get the syntactic sugar for the SST supported targets
ö
I also need to pass the eventBus environment variable to a lambda
I guess I have a couple options:
.env
,
stacks/index.js
or basically the stack in which I’m defining the EventBus
So basically I did this, but I’m not sure if it is the best practice:
Copy code
import * as sst from '@serverless-stack/resources'
import * as events from '@aws-cdk/aws-events'
import * as targets from '@aws-cdk/aws-events-targets'

const handlerDir = 'src/handlers/'

export class MainStack extends sst.Stack {
      constructor(scope: <http://sst.App|sst.App>, id: string, props?: sst.StackProps) {
            super(scope, id, props)
            const eventBus = new events.EventBus(this, id, {
                  eventBusName: 'FallbackBus'
            })
            const snsTopic = new sst.Topic(this, 'SNSTopic', {
                  snsTopic: {
                        topicName: 'FallbackTopic',
                  }
            })
            const snsTarget = new targets.SnsTopic(snsTopic.snsTopic)
            new events.Rule(this, 'FallbackRule', {
                  description: 'Put events to SNS Topic',
                  eventBus,
                  ruleName: 'FallbackRule',
                  targets: [snsTarget],
                  eventPattern: {
                        account: [scope.account],
                  }
            })
            const api = new sst.ApiGatewayV1Api(this, 'Api', {
                  defaultFunctionProps: {
                        environment: {
                              eventBusName: eventBus.eventBusName
                        }
                  },
                  routes: {
                        'POST /create-event': handlerDir + 'apiGateway/create-event/index.main'
                  }
            })

            this.addOutputs({
                  EventBusName: eventBus.eventBusName,
                  EventBusArn: eventBus.eventBusArn,
                  SNSTopicName: snsTopic.topicName,
                  SNSTopicArn: snsTopic.topicArn,
                  RESTEndpoint: api.url
            })
      }
}
o
Yeah I do basically the same thing except my eventbus is in its own stack, which exports the name like you do, which then gets passed into another stack that has the rule and the handler. The API gateway has its own stack too.
ö
I see, thanks!
I additionally created a declaration file as
environment.d.ts
Copy code
declare namespace NodeJS {
      interface ProcessEnv {
            eventBusName: string
      }
}
This helps
Tho I could not use the global space like this:
Copy code
declare global {
      namespace NodeJS {
            interface ProcessEnv {
                  eventBusName: string
            }
      }
}
o
Ah nice, never thought of doing that
ö
IntelliSense suggest the environment variable name