Creating an SNS Fanout in Serverless
Previously we've covered what the Barstool Queue Engine is and how we use it for long-running services. Our next problem was how to handle alerting our various services that those jobs had finished or errored. As we rely heavily on the Serverless framework, we implemented this principle using their tools. The idea of an SNS fanout is to send out messages to a single SNS topic that any SQS handler could listen to and interpret. To begin, we need a new topic, MyOutputTopic
, created as follows that utilizes a multi-stage deployment:
Since our services are in separate repositories, we also need to make sure the ARN of that topic is accessible outside of this single serverless deployment. Serverless provides an Output
implementation to direct our stack to export values:
In our other repositories, we built out SQS queues in Serverless that subscribe to a singular topic. We had to create access policies so that we had permission to read from the topic:
Now we have an SQS queue Service2Queue
that is listening to all messages sent to the MyOutputTopic-${opt:stage}
topic. This would have been enough if we truly cared about receiving everything but we don't, so as an additional step we employed SQS filters to limit what each queue would receive. When we send messages to BQE we include the following snippet as part of the message:
Once the above exists on a message the Serverless definition for the subscription can be updated to include a FilterPolicy
to limit the invocations to only the messages that the queue needs to handle:
The last piece of code to drive this home is to hook the subscription into a lambda function to process the messages:
functions:
MyOutputTopicQueue:
handler: handlers/sqs.myOutputTopic
events:
- sqs:
arn:
Fn::GetAtt: [Service2Queue, Arn]
batchSize: 10
SNS fanouts have proven incredibly helpful for our needs. I've put all this yml
together in a Gist for easy reference. To learn more about SNS, Amazon has additional information here.