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

pilgrim2go commented Jul 1, 2016

You save my day. Thanks for sharing

@Nath-P

This comment has been minimized.

Copy link

Nath-P 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

cwlucas41 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