Add function to allow adding SNS subscriptions

CloudFormation currently only supports adding subscriptions at the time
the SNS topic is created; it does not support subscribing to existing
SNS topics.
This commit is contained in:
Ryan Martin 2015-12-30 13:23:36 -05:00
parent 73e0df1c53
commit db42f0bf9c
4 changed files with 127 additions and 2 deletions

3
.gitignore vendored
View file

@ -25,3 +25,6 @@ build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
# Other local things to ignore
cloudformation-helpers.zip

View file

@ -89,6 +89,25 @@ A JSON array of items to be inserted, in JSON format (not DynamoDB format).
DynamoDBPutItemsFunctionArn
### Subscribe to SNS topics
Mirrors the SNS.Subscribe API method (http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html#subscribe-property).
#### Parameters
##### Endpoint
The endpoint that receives the SNS messages.
##### Protocol
The type of endpoint. Can be one of the following values: application, email, email-json, http, https, lambda, sms, sqs.
##### TopicArn
The SNS topic to subscribe to.
#### Reference Output Name
SnsSubscribeFunctionArn
## Deployment (contributors)
After making changes (i.e. adding a new helper function), please do the following:

View file

@ -1,6 +1,7 @@
var AWS = require('aws-sdk');
var dynamoDB = new AWS.DynamoDB();
var response = require('./lib/cfn-response');
var sns = new AWS.SNS();
exports.dynamoDBPutItems = function(event, context) {
var p = event.ResourceProperties;
@ -11,13 +12,43 @@ exports.dynamoDBPutItems = function(event, context) {
if (!Array.isArray(p.Items)) {
error("Must specify a list of items to insert.", event, context);
} else if (p.TableName === undefined) {
} else if (!p.TableName) {
error("Must specify a table to insert into.", event, context);
} else {
putItems(p.Items, p.TableName, event, context, []);
}
}
// Exposes the SNS.subscribe API method
exports.snsSubscribe = function(event, context) {
const allowedProtocols = ['application', 'email', 'email-json', 'http', 'https', 'lambda', 'sms', 'sqs'];
var p = event.ResourceProperties;
if (event.RequestType == 'Delete') {
response.send(event, context, response.SUCCESS);
return;
}
if (!p.TopicArn) {
error("Must specify a TopicArn to subscribe to.", event, context);
} else if (!p.Endpoint) {
error("Must specify an Endpoint that receives messages.", event, context);
} else if (allowedProtocols.indexOf(p.Protocol) < 0) {
error("Must speficy one of these supported protocols: " + allowedProtocols, event, context);
} else {
sns.subscribe({
Endpoint: p.Endpoint,
Protocol: p.Protocol,
TopicArn: p.TopicArn
}, function(err, data) {
if (err) {
error(err, event, context);
} else {
response.send(event, context, response.SUCCESS, { "SubscriptionArn": data.SubscriptionArn });
}
});
}
}
// Puts items into DynamoDB, iterating over the list recursively.
function putItems(items, tableName, event, context, itemsInserted) {
if(items.length > 0){
@ -77,4 +108,4 @@ function formatForDynamo(value, topLevel) {
function error(message, event, context) {
console.error(message);
response.send(event, context, response.FAILED, { Error: message });
}
}

View file

@ -68,12 +68,84 @@
"DependsOn": [
"DynamoDBPutItemsFunctionRole"
]
},
"SnsSubscribeFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [ "lambda.amazonaws.com" ]
},
"Action": [ "sts:AssumeRole" ]
}
]
},
"Policies": [
{
"PolicyName": "LogWriter",
"PolicyDocument": {
"Version" : "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
},
{
"PolicyName": "SNSSubscriber",
"PolicyDocument": {
"Version" : "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:subscribe"
],
"Resource": "*"
}
]
}
}
]
}
},
"SnsSubscribeFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "com.gilt.public.backoffice",
"S3Key": "lambda_functions/cloudformation-helpers.zip"
},
"Description": "Used to subscribe to existing SNS topics.",
"Handler": "cloudformation_helpers.snsSubscribe",
"Role": {"Fn::GetAtt" : [ "SnsSubscribeFunctionRole", "Arn" ] },
"Runtime": "nodejs",
"Timeout": 30
},
"DependsOn": [
"SnsSubscribeFunctionRole"
]
}
},
"Outputs": {
"DynamoDBPutItemsFunctionArn": {
"Description": "The ARN of the DynamoDBPutItemsFunction, for use in other CloudFormation templates.",
"Value": { "Fn::GetAtt" : ["DynamoDBPutItemsFunction", "Arn"] }
},
"SnsSubscribeFunctionArn": {
"Description": "The ARN of the SnsSubscribeFunction, for use in other CloudFormation templates.",
"Value": { "Fn::GetAtt" : ["SnsSubscribeFunction", "Arn"] }
}
}
}