Created
April 7, 2020 15:57
-
-
Save zaccharles/a6e229409282eacff7ff1447a90dc5ca to your computer and use it in GitHub Desktop.
Deprecate SNS Topic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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