💡 Overview
Setting up Amazon SNS to SQS subscriptions within the same AWS account is usually smooth. But when it comes to cross-account integration, it becomes tricky due to IAM policies and permission constraints.
This guide explains how to properly configure a cross-account SNS ➝ SQS ➝ Lambda system with full security and reliability.
📘 Use Case
- You have an SNS Topic in Account A
- You have an SQS Queue in Account B
- Your goal is for SNS in Account A to push events to the SQS in Account B
- SQS then triggers your Lambda function to process the events
⚙️ Required Setup
1. ✅ SNS Topic Policy (In Account A)
Account A must allow Account B to subscribe to its SNS topic. Here’s a sample resource policy to attach to the SNS topic:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCrossAccountSubscription", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:root" // Account B's AWS Account ID }, "Action": "sns:Subscribe", "Resource": "arn:aws:sns:us-east-1:111111111111:your-topic-name", "Condition": { "StringEquals": { "AWS:SourceOwner": "123456789012" } } } ] }
📝 Replace 123456789012
with Account B’s ID and update the SNS ARN as needed.
⚠️ Important Note:
Only the root user or an IAM user/role with the right permissions can call
sns:Subscribe
.
Even if Account A allows the subscription, if the user or role in Account B does not have thesns:Subscribe
permission, it still cannot subscribe.
2. ✅ SQS Queue Policy (In Account B)
Account B’s SQS queue needs permission to accept messages from Account A’s SNS topic:
SQSQueuePolicy: Type: AWS::SQS::QueuePolicy Properties: PolicyDocument: Version: "2012-10-17" Statement: - Sid: AllowSNSSend Effect: Allow Principal: Service: sns.amazonaws.com Action: "sqs:SendMessage" Resource: !GetAtt MyQueue.Arn Condition: ArnEquals: aws:SourceArn: arn:aws:sns:us-east-1:111111111111:your-topic-name Queues: - !Ref MyQueue
This ensures SNS in Account A can push to the queue in Account B securely.
3. ✅ Cross-Account Subscription (CloudFormation/Serverless)
From Account B, create a subscription to the SNS topic in Account A:
CrossAccountSubscription: Type: AWS::SNS::Subscription Properties: TopicArn: arn:aws:sns:us-east-1:111111111111:your-topic-name Protocol: sqs Endpoint: !GetAtt MyQueue.Arn RawMessageDelivery: true
💡 Note: If you manually subscribed before via console and try to redeploy via IaC, you may get this error:
Subscription already exists with different attributes
🧼 Fix: Go to the SNS console → find the subscription → delete it first before deploying again.
🧪 Tips for Testing
- Confirm SNS topic has the correct resource policy.
- Validate that SQS allows
sns:SendMessage
from the topic. - Use CloudTrail or logs to trace errors.
- Avoid overlapping manual + IaC subscriptions to prevent attribute mismatch.
✅ Final Result
After correct setup:
- SNS in Account A can now send events to SQS in Account B
- The Lambda function behind the SQS can now process the event data
- You can extend this by adding DLQs or S3 logging for failed messages
🧠 Lessons Learned
- Cross-account SNS ➝ SQS setup needs cooperation from both ends.
- Be cautious with manual subscriptions — they can block your CloudFormation deployment.
- Resource-based policies are mandatory for cross-account messaging.
- Using raw message delivery keeps the payload clean and easy to parse.
📌 Conclusion
This setup is a must-know for event-driven architectures across multiple AWS accounts. Keep this reference handy and share it with your team if you’re planning cross-account systems in AWS.
If you’d like a template or have issues replicating this, feel free to reach out via the contact form on linuxbeast.com.