Skip to content

Instantly share code, notes, and snippets.

@zaccharles
Created April 7, 2020 15:57
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 zaccharles/a6e229409282eacff7ff1447a90dc5ca to your computer and use it in GitHub Desktop.
Save zaccharles/a6e229409282eacff7ff1447a90dc5ca to your computer and use it in GitHub Desktop.
Deprecate SNS Topic
/*
Problem:
There is an SNS topic that you wish to get rid of so you "deprecate" it.
The idea is to get migrate each subscriber away one by one then eventually
delete the topic.
However, this can be difficult without something stopping new subscribers
from adding new dependencies.
Solution:
This script takes an SNS topic ARN and adds a new statement to its access policy.
The new statement prevents new endpoints from being subscribed to the topic.
Existing subscriptions can still be recreated because they will be whitelisted.
This script can be run again to remove unsubscribed endpoints from the whitelist.
Usage:
1. Run `npm install`
2. Set environment variables:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN (optional)
AWS_REGION
3. Run `node deprecate-topic.js <Topic ARN>
Example: node deprecate-topic.js arn:aws:sns:eu-west-1:123456789069:topic-name
*/
(async () => {
try {
const AWS = require('aws-sdk')
const sns = new AWS.SNS()
const sid = 'DeprecateTopic'
const topicArn = process.argv[2]
// Get current access control policy
let response = await sns.getTopicAttributes({
TopicArn: topicArn
}).promise()
let policy = JSON.parse(response.Attributes.Policy)
policy.Statement = policy.Statement.filter(s => s.Sid !== sid)
// List currently subscribed endpoints
response = await sns.listSubscriptionsByTopic({
TopicArn: topicArn
}).promise()
let endpoints = response.Subscriptions.reduce((a, cv) => {
a.push(cv.Endpoint)
return a
}, [])
// Append or update deprecation statement
let statement = {
Sid: sid,
Effect: 'Deny',
Principal: {
AWS: '*'
},
Action: 'SNS:Subscribe',
Resource: topicArn,
Condition: {
StringNotEquals: {
'SNS:Endpoint': endpoints
}
}
}
policy.Statement.push(statement)
policy = JSON.stringify(policy, null, 2)
// Set new access control policy
response = await sns.setTopicAttributes({
TopicArn: topicArn,
AttributeName: 'Policy',
AttributeValue: policy
}).promise()
console.log('Success')
console.log(policy)
} catch (err) {
console.error(err)
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment