Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
AWS CloudFormation SNS Subscription
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"Topic": {
"Type": "AWS::SNS::Topic",
"Properties": {
}
},
"Queue": {
"Type": "AWS::SQS::Queue",
"Properties": {
}
},
"Subscription": {
"Type": "Custom::TopicSubscription",
"DependsOn": ["FunctionTopicSubscription"],
"Properties": {
"ServiceToken": { "Fn::GetAtt": ["FunctionTopicSubscription", "Arn"] },
"TopicArn": { "Ref": "Topic" },
"Endpoint": { "Fn::GetAtt": [ "Queue", "Arn" ] },
"Protocol": "sqs"
}
},
"FunctionTopicSubscription": {
"Type": "AWS::Lambda::Function",
"DependsOn": ["LambdaExecutionRole"],
"Properties": {
"Handler": "index.handler",
"Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] },
"Code": {
"ZipFile": { "Fn::Join": ["\n", [
"var response = require('cfn-response');",
"exports.handler = function(event, context) {",
" console.log('REQUEST RECEIVED:\\n', JSON.stringify(event));",
" var responseData = {};",
" if (event.RequestType == 'Delete') {",
" var subscriptionArn = event.PhysicalResourceId;",
" var aws = require('aws-sdk');",
" var sns = new aws.SNS();",
" sns.unsubscribe({SubscriptionArn: subscriptionArn}, function(err, data) {",
" if (err) {",
" responseData = {Error: 'Failed to unsubscribe from SNS Topic'};",
" response.send(event, context, response.FAILED, responseData);",
" } else {",
" response.send(event, context, response.SUCCESS, data, data.SubscriptionArn);",
" }",
" });",
" return;",
" }",
" if (event.RequestType == 'Create' || event.RequestType == 'Update') {",
" var topicArn = event.ResourceProperties.TopicArn;",
" var endpoint = event.ResourceProperties.Endpoint;",
" var protocol = event.ResourceProperties.Protocol;",
" if (topicArn && endpoint && protocol) {",
" var aws = require('aws-sdk');",
" var sns = new aws.SNS();",
" sns.subscribe({TopicArn: topicArn, Endpoint: endpoint, Protocol: protocol}, function(err, data) {",
" if (err) {",
" responseData = {Error: 'Failed to subscribe to SNS Topic'};",
" console.log(responseData.Error + ':\\n', err);",
" response.send(event, context, response.FAILED, responseData);",
" } else {",
" response.send(event, context, response.SUCCESS, data, data.SubscriptionArn);",
" }",
" });",
" } else {",
" responseData = {Error: 'Missing one of required arguments'};",
" console.log(responseData.Error);",
" response.send(event, context, response.FAILED, responseData);",
" }",
" }",
"};"
]]}
},
"Runtime": "nodejs",
"Timeout": "30"
}
},
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": ["lambda.amazonaws.com"]},
"Action": ["sts:AssumeRole"]
}]
},
"Path": "/",
"Policies": [{
"PolicyName": "DescribeStack",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"],
"Resource": "arn:aws:logs:*:*:*"
}, {
"Effect": "Allow",
"Action": [
"sns:Subscribe",
"sns:Unsubscribe"
],
"Resource": { "Ref": "Topic" }
}]
}
}]
}
}
}
}
@pilgrim2go

This comment has been minimized.

Copy link

commented Jul 1, 2016

You save my day. Thanks for sharing

@Nath-P

This comment has been minimized.

Copy link

commented Nov 12, 2016

Thanks, this saved me tones of time!!

I've added cross region support to it: https://gist.github.com/Nath-P/899e5e021b9a19b3e601ccae083606fb as a lot of the the topics I want to subscribe to are in a region other than the one my SQS/ Clouldformation stack is in.

basically I just parse the topc ARN to determine which region the topic is in.

@cwlucas41

This comment has been minimized.

Copy link

commented Jun 13, 2018

@martinssipenko Is there a license on this Gist? I'd like to use it in my project.

@cyrfer

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.