Automate Amazon SNS to Amazon SQS messaging with Amazon CloudFormation
Amazon CloudFormation enables you to use a template file to create and configure a collection of Amazon resources together as a single unit. This section has an example template that makes it easy to deploy topics that publish to queues. The templates take care of the setup steps for you by creating two queues, creating a topic with subscriptions to the queues, adding a policy to the queues so that the topic can send messages to the queues, and creating IAM users and groups to control access to those resources.
For more information about deploying Amazon resources using an Amazon CloudFormation template, see Get Started in the Amazon CloudFormation User Guide.
Using an Amazon CloudFormation template to set up topics and queues within an Amazon Web Services account
The example template creates an Amazon SNS topic that can send messages to two Amazon SQS queues with appropriate permissions for members of one IAM group to publish to the topic and another to read messages from the queues. The template also creates IAM users that are added to each group.
You copy the template contents into a file. You can also download the template from the
Amazon
CloudFormation Templates page
MySNSTopic is set up to publish to two subscribed endpoints, which are two Amazon SQS queues
(MyQueue1 and MyQueue2). MyPublishTopicGroup is an IAM group whose members have permission
to publish to MySNSTopic using the Publish
API action or sns-publish
MyRDMessageQueueGroup is an IAM group whose members have permission to read and delete messages from the two Amazon SQS queues using the ReceiveMessage and DeleteMessage API actions. AddUserToMyQueueGroup adds MyQueueUser to the MyRDMessageQueueGroup so that the user will have the permissions assigned to the group. MyQueuePolicy assigns permission for MySNSTopic to publish its notifications to the two queues.
The following listing shows the Amazon CloudFormation template contents.
{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation Sample Template SNSToSQS: This Template creates an SNS topic that can send messages to two SQS queues with appropriate permissions for one IAM user to publish to the topic and another to read messages from the queues. MySNSTopic is set up to publish to two subscribed endpoints, which are two SQS queues (MyQueue1 and MyQueue2). MyPublishUser is an IAM user that can publish to MySNSTopic using the Publish API. MyTopicPolicy assigns that permission to MyPublishUser. MyQueueUser is an IAM user that can read messages from the two SQS queues. MyQueuePolicy assigns those permissions to MyQueueUser. It also assigns permission for MySNSTopic to publish its notifications to the two queues. The template creates access keys for the two IAM users with MyPublishUserKey and MyQueueUserKey. ***Warning*** you will be billed for the Amazon resources used if you create a stack from this template.", "Parameters": { "MyPublishUserPassword": { "NoEcho": "true", "Type": "String", "Description": "Password for the IAM user MyPublishUser", "MinLength": "1", "MaxLength": "41", "AllowedPattern": "[a-zA-Z0-9]*", "ConstraintDescription": "must contain only alphanumeric characters." }, "MyQueueUserPassword": { "NoEcho": "true", "Type": "String", "Description": "Password for the IAM user MyQueueUser", "MinLength": "1", "MaxLength": "41", "AllowedPattern": "[a-zA-Z0-9]*", "ConstraintDescription": "must contain only alphanumeric characters." } }, "Resources": { "MySNSTopic": { "Type": "AWS::SNS::Topic", "Properties": { "Subscription": [{ "Endpoint": { "Fn::GetAtt": ["MyQueue1", "Arn"] }, "Protocol": "sqs" }, { "Endpoint": { "Fn::GetAtt": ["MyQueue2", "Arn"] }, "Protocol": "sqs" } ] } }, "MyQueue1": { "Type": "AWS::SQS::Queue" }, "MyQueue2": { "Type": "AWS::SQS::Queue" }, "MyPublishUser": { "Type": "AWS::IAM::User", "Properties": { "LoginProfile": { "Password": { "Ref": "MyPublishUserPassword" } } } }, "MyPublishUserKey": { "Type": "AWS::IAM::AccessKey", "Properties": { "UserName": { "Ref": "MyPublishUser" } } }, "MyPublishTopicGroup": { "Type": "AWS::IAM::Group", "Properties": { "Policies": [{ "PolicyName": "MyTopicGroupPolicy", "PolicyDocument": { "Statement": [{ "Effect": "Allow", "Action": [ "sns:Publish" ], "Resource": { "Ref": "MySNSTopic" } }] } }] } }, "AddUserToMyPublishTopicGroup": { "Type": "AWS::IAM::UserToGroupAddition", "Properties": { "GroupName": { "Ref": "MyPublishTopicGroup" }, "Users": [{ "Ref": "MyPublishUser" }] } }, "MyQueueUser": { "Type": "AWS::IAM::User", "Properties": { "LoginProfile": { "Password": { "Ref": "MyQueueUserPassword" } } } }, "MyQueueUserKey": { "Type": "AWS::IAM::AccessKey", "Properties": { "UserName": { "Ref": "MyQueueUser" } } }, "MyRDMessageQueueGroup": { "Type": "AWS::IAM::Group", "Properties": { "Policies": [{ "PolicyName": "MyQueueGroupPolicy", "PolicyDocument": { "Statement": [{ "Effect": "Allow", "Action": [ "sqs:DeleteMessage", "sqs:ReceiveMessage" ], "Resource": [{ "Fn::GetAtt": ["MyQueue1", "Arn"] }, { "Fn::GetAtt": ["MyQueue2", "Arn"] } ] }] } }] } }, "AddUserToMyQueueGroup": { "Type": "AWS::IAM::UserToGroupAddition", "Properties": { "GroupName": { "Ref": "MyRDMessageQueueGroup" }, "Users": [{ "Ref": "MyQueueUser" }] } }, "MyQueuePolicy": { "Type": "AWS::SQS::QueuePolicy", "Properties": { "PolicyDocument": { "Statement": [{ "Effect": "Allow", "Principal": { "Service": "sns.amazonaws.com" }, "Action": ["sqs:SendMessage"], "Resource": "*", "Condition": { "ArnEquals": { "aws:SourceArn": { "Ref": "MySNSTopic" } } } }] }, "Queues": [{ "Ref": "MyQueue1" }, { "Ref": "MyQueue2" }] } } }, "Outputs": { "MySNSTopicTopicARN": { "Value": { "Ref": "MySNSTopic" } }, "MyQueue1Info": { "Value": { "Fn::Join": [ " ", [ "ARN:", { "Fn::GetAtt": ["MyQueue1", "Arn"] }, "URL:", { "Ref": "MyQueue1" } ] ] } }, "MyQueue2Info": { "Value": { "Fn::Join": [ " ", [ "ARN:", { "Fn::GetAtt": ["MyQueue2", "Arn"] }, "URL:", { "Ref": "MyQueue2" } ] ] } }, "MyPublishUserInfo": { "Value": { "Fn::Join": [ " ", [ "ARN:", { "Fn::GetAtt": ["MyPublishUser", "Arn"] }, "Access Key:", { "Ref": "MyPublishUserKey" }, "Secret Key:", { "Fn::GetAtt": ["MyPublishUserKey", "SecretAccessKey"] } ] ] } }, "MyQueueUserInfo": { "Value": { "Fn::Join": [ " ", [ "ARN:", { "Fn::GetAtt": ["MyQueueUser", "Arn"] }, "Access Key:", { "Ref": "MyQueueUserKey" }, "Secret Key:", { "Fn::GetAtt": ["MyQueueUserKey", "SecretAccessKey"] } ] ] } } } }