Skip to content

Instantly share code, notes, and snippets.

@kylejmhudson
Forked from DavidWells/serverless.yml
Created January 22, 2020 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kylejmhudson/40d129527a9ce37d873a7f6c5ae06c3a to your computer and use it in GitHub Desktop.
Save kylejmhudson/40d129527a9ce37d873a7f6c5ae06c3a to your computer and use it in GitHub Desktop.
Creating a custom serverless resource for subscribing to SNS topics in another region
# Welcome to Serverless!
#
# Happy Coding!
service: cross-region-sns-subscriber
# Keep environment specific configurations in separate files
custom: ${file(config/${env:STAGE}.json)}
provider:
name: aws
runtime: nodejs6.10
stage: ${env:STAGE}
region: ${self:custom.environment.region}
role: arn:aws:iam::${self:custom.environment.account}:role/${self:custom.environment.lambdaRoleName}
environment:
STAGE: ${self:provider.stage}
functions:
processSns:
handler: handler.sns # entrypoint to your lambda
memorySize: 512
timeout: 30
events:
- sns: ${self:custom.sns.arn}
# Below function is used by cloudformation to create the sns subscription
topicSubscription:
handler: topic.subscription
memorySize: 256
timeout: 30
resources:
Resources:
# This resource has to match the name of the generated SNS subscription resource
# in order for it to override the implementation
ProcessSnsSnsSubscriptionMyTopic:
Type: Custom::TopicSubscription
DependsOn:
- TopicSubscriptionLambdaFunction
Properties:
ServiceToken:
Fn::GetAtt:
- TopicSubscriptionLambdaFunction
- Arn
TopicArn: ${self:custom.sns.arn}
Endpoint:
Fn::GetAtt:
- ProcessSnsLambdaFunction
- Arn
Protocol: lambda
'use strict';
/*
This was adapted from https://gist.github.com/Nath-P/899e5e021b9a19b3e601ccae083606fb
*/
const response = require('cfn-response');
const aws = require('aws-sdk');
module.exports.subscription = (event, context) => {
console.log('REQUEST RECEIVED:\n', JSON.stringify(event));
let responseData = {};
if (event.RequestType === 'Delete') {
let subscriptionArn = event.PhysicalResourceId;
let region = subscriptionArn.split(':')[3];
aws.config.update({region: region});
let 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);
}
});
}
else if (event.RequestType === 'Create' || event.RequestType === 'Update') {
let topicArn = event.ResourceProperties.TopicArn;
let endpoint = event.ResourceProperties.Endpoint;
let protocol = event.ResourceProperties.Protocol;
let region = topicArn.split(':')[3];
if (topicArn && endpoint && protocol) {
aws.config.update({region: region});
let 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);
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment