A use case happened at work recently, where we need to subscribe a SQS queue to a SNS topic running in another AWS account. On the surface this seems like something many people would need to do, and indeed I was able to find an official tutorial pretty quickly. But the tutorial is all “click this in the SQS console, and do that in the SNS console”. We are strong believers in Infrastructure as Code and having someone do the subscription steps manually is not going to work, especially given that we’ll be repeating this process in many places.
So here’s what I learnt as I translate the tutorial steps into CloudFormation, and some gotchas I found.
First, in the SNS account, you need to add a SNS TopicPolicy to give the SQS account permission to call sns:Subscribe on the relevant topic(s).
Then, in the SQS account, you need to create:
- A SQS QueuePolicy to allow the above SNS topic to call SQS:SendMessage against the relevant SQS queue(s). The big gotcha here is that, unlike anywhere else in IAM land, the SQS action is prefixed with SQS, not the usual sqs! This might be owing to the fact that SQS is the oldest service in AWS and predates the conventions we know. Nonetheless, it was a difficult problem to track down.
- Create the SNS Subscription in the SQS account. When you create the subscription in the SQS account, you don’t need to explicitly confirm the subscription. If you create the SNS subscription in the SNS account, then a confirm subscription message is sent to the SQS queue first, which you would need to handle to confirm the subscription.
All in all, it was pretty straight forward once I figured out the magic incantation to make it work.
Another behaviour difference that I didn’t anticipate was how the SNS Filter Policy affects the structure of the message I would receive in the SQS queue.
If I publish the following message to the SNS topic.
If Filter Policy is not set on the subscription then the SQS queue would receive a message like this:
The SNS message attributes are included as part of the JSON message body.
And not in the SQS message attributes.
If Filter Policy is set on the SNS subscription, then the SQS queue would receive a message like this instead:
And the SNS message attributes are forwarding on as SQS message attributes.
Again, this behavioural difference seems pretty random. By filtering what messages I choose to receive I somehow receive messages in a completely different format…
Anyhow, I hope you find this useful, and hopefully it saves you half an hour of head scratching!
Enjoy what you’re reading? Subscribe to my newsletter and get more content on AWS and serverless technologies delivered straight to your inbox.
I’m an AWS Serverless Hero and the author of Production-Ready Serverless. I have run production workload at scale in AWS for nearly 10 years and I have been an architect or principal engineer with a variety of industries ranging from banking, e-commerce, sports streaming to mobile gaming. I currently work as an independent consultant focused on AWS and serverless.
In this course, we’ll cover everything you need to know to use AWS Step Functions service effectively. Including basic concepts, HTTP and event triggers, activities, design patterns and best practices.
Come learn about operational BEST PRACTICES for AWS Lambda: CI/CD, testing & debugging functions locally, logging, monitoring, distributed tracing, canary deployments, config management, authentication & authorization, VPC, security, error handling, and more.
You can also get 40% off the face price with the code ytcui.
Here is a complete list of all my posts on serverless and AWS Lambda. In the meantime, here are a few of my most popular blog posts.
- Lambda optimization tip – enable HTTP keep-alive
- You are thinking about serverless costs all wrong
- Many faced threats to Serverless security
- We can do better than percentile latencies
- I’m afraid you’re thinking about AWS Lambda cold starts all wrong
- Yubl’s road to Serverless
- AWS Lambda – should you have few monolithic functions or many single-purposed functions?
- AWS Lambda – compare coldstart time with different languages, memory and code sizes
- Guys, we’re doing pagination wrong