Skip to content

Commit

Permalink
fix(sns): create subscription object under subscriber (#1645)
Browse files Browse the repository at this point in the history
Create the SNS Subscription object under the subscriber
instead of the subscribee, avoiding cyclic stack dependencies
if those objects would be in different stacks.

Fixes #1643, fixes #1534.

DEPLOYMENT IMPACT: this will recreate any subscription objects under new
names. It should not have visible impact on your deployments.
  • Loading branch information
rix0rrr authored Feb 6, 2019
1 parent 823a1e8 commit 0cc11ca
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@
"MyTopic86869434": {
"Type": "AWS::SNS::Topic"
},
"MyTopicMyQueueSubscription3245B11E": {
"MyQueueMyTopicSubscriptionEB66AD1B": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@
"EcsClusterDefaultAutoScalingGroupDrainECSHookTopicC705BD25": {
"Type": "AWS::SNS::Topic"
},
"EcsClusterDefaultAutoScalingGroupDrainECSHookTopicFunctionSubscription4313BD38": {
"EcsClusterDefaultAutoScalingGroupDrainECSHookFunctionTopicSubscriptionDA5F8A10": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
Expand Down Expand Up @@ -1090,4 +1090,4 @@
"Description": "S3 key for asset version \"aws-ecs-integ-ecs/AdoptEcrRepositorydbc60defc59544bcaa5c28c95d68f62c/Code\""
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@
"EcsClusterDefaultAutoScalingGroupDrainECSHookTopicC705BD25": {
"Type": "AWS::SNS::Topic"
},
"EcsClusterDefaultAutoScalingGroupDrainECSHookTopicFunctionSubscription4313BD38": {
"EcsClusterDefaultAutoScalingGroupDrainECSHookFunctionTopicSubscriptionDA5F8A10": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@
"EcsClusterDefaultAutoScalingGroupDrainECSHookTopicC705BD25": {
"Type": "AWS::SNS::Topic"
},
"EcsClusterDefaultAutoScalingGroupDrainECSHookTopicFunctionSubscription4313BD38": {
"EcsClusterDefaultAutoScalingGroupDrainECSHookFunctionTopicSubscriptionDA5F8A10": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"TD925BC7E": {
"Type": "AWS::SNS::Topic"
},
"TFSubscription47A24A95": {
"FTSubscription775EAF05": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
Expand All @@ -82,4 +82,4 @@
}
}
}
}
}
25 changes: 18 additions & 7 deletions packages/@aws-cdk/aws-sns/lib/topic-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,19 @@ export abstract class TopicBase extends cdk.Construct implements ITopic {
* @param queue The target queue
*/
public subscribeQueue(queue: sqs.IQueue): Subscription {
const subscriptionName = queue.node.id + 'Subscription';
if (this.node.tryFindChild(subscriptionName)) {
if (!cdk.Construct.isConstruct(queue)) {
throw new Error(`The supplied Queue object must be an instance of Construct`);
}

const subscriptionName = this.node.id + 'Subscription';
if (queue.node.tryFindChild(subscriptionName)) {
throw new Error(`A subscription between the topic ${this.node.id} and the queue ${queue.node.id} already exists`);
}

// we use the queue name as the subscription's. there's no meaning to subscribing
// the same queue twice on the same topic.
const sub = new Subscription(this, subscriptionName, {
// the same queue twice on the same topic. Create subscription under *consuming*
// construct to make sure it ends up in the correct stack in cases of cross-stack subscriptions.
const sub = new Subscription(queue, subscriptionName, {
topic: this,
endpoint: queue.queueArn,
protocol: SubscriptionProtocol.Sqs
Expand All @@ -170,13 +175,19 @@ export abstract class TopicBase extends cdk.Construct implements ITopic {
* @param lambdaFunction The Lambda function to invoke
*/
public subscribeLambda(lambdaFunction: lambda.IFunction): Subscription {
const subscriptionName = lambdaFunction.id + 'Subscription';
if (!cdk.Construct.isConstruct(lambdaFunction)) {
throw new Error(`The supplied lambda Function object must be an instance of Construct`);
}

const subscriptionName = this.node.id + 'Subscription';

if (this.node.tryFindChild(subscriptionName)) {
if (lambdaFunction.node.tryFindChild(subscriptionName)) {
throw new Error(`A subscription between the topic ${this.node.id} and the lambda ${lambdaFunction.id} already exists`);
}

const sub = new Subscription(this, subscriptionName, {
// Create subscription under *consuming* construct to make sure it ends up
// in the correct stack in cases of cross-stack subscriptions.
const sub = new Subscription(lambdaFunction, subscriptionName, {
topic: this,
endpoint: lambdaFunction.functionArn,
protocol: SubscriptionProtocol.Lambda
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,21 @@
"MyTopic86869434": {
"Type": "AWS::SNS::Topic"
},
"MyTopicMyQueueSubscription3245B11E": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
"Fn::GetAtt": [
"MyQueueE6CA6235",
"Arn"
]
},
"Protocol": "sqs",
"TopicArn": {
"Ref": "MyTopic86869434"
}
}
},
"MyTopicPolicy12A5EC17": {
"Type": "AWS::SNS::TopicPolicy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Sid": "0",
"Action": "sns:Publish",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Resource": {
"Ref": "MyTopic86869434"
}
},
"Sid": "0"
}
],
"Version": "2012-10-17"
Expand Down Expand Up @@ -62,6 +47,21 @@
"MyQueueE6CA6235": {
"Type": "AWS::SQS::Queue"
},
"MyQueueMyTopicSubscriptionEB66AD1B": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
"Fn::GetAtt": [
"MyQueueE6CA6235",
"Arn"
]
},
"Protocol": "sqs",
"TopicArn": {
"Ref": "MyTopic86869434"
}
}
},
"MyQueuePolicy6BBEDDAC": {
"Type": "AWS::SQS::QueuePolicy",
"Properties": {
Expand Down
45 changes: 28 additions & 17 deletions packages/@aws-cdk/aws-sns/test/integ.sns-lambda.expected.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,6 @@
"MyTopic86869434": {
"Type": "AWS::SNS::Topic"
},
"MyTopicEchoSubscription021036AD": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
"Fn::GetAtt": [
"Echo11F3FB29",
"Arn"
]
},
"Protocol": "lambda",
"TopicArn": {
"Ref": "MyTopic86869434"
}
}
},
"EchoServiceRoleBE28060B": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand All @@ -34,7 +19,18 @@
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{"Fn::Join":["",["arn:",{"Ref":"AWS::Partition"},":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]]}
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
]
]
}
]
}
},
Expand All @@ -57,6 +53,21 @@
"EchoServiceRoleBE28060B"
]
},
"EchoMyTopicSubscriptionA634C6D7": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
"Fn::GetAtt": [
"Echo11F3FB29",
"Arn"
]
},
"Protocol": "lambda",
"TopicArn": {
"Ref": "MyTopic86869434"
}
}
},
"EchoMyTopicF6EBB45F": {
"Type": "AWS::Lambda::Permission",
"Properties": {
Expand All @@ -71,4 +82,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"MyTopic86869434": {
"Type": "AWS::SNS::Topic"
},
"MyTopicMyQueueSubscription3245B11E": {
"MyQueueE6CA6235": {
"Type": "AWS::SQS::Queue"
},
"MyQueueMyTopicSubscriptionEB66AD1B": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
Expand All @@ -18,9 +21,6 @@
}
}
},
"MyQueueE6CA6235": {
"Type": "AWS::SQS::Queue"
},
"MyQueuePolicy6BBEDDAC": {
"Type": "AWS::SQS::QueuePolicy",
"Properties": {
Expand Down
8 changes: 4 additions & 4 deletions packages/@aws-cdk/aws-sns/test/test.sns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export = {
"TopicName": "topicName"
}
},
"MyTopicMyQueueSubscription3245B11E": {
"MyQueueMyTopicSubscriptionEB66AD1B": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
Expand Down Expand Up @@ -233,7 +233,7 @@ export = {
"TopicName": "topicName"
}
},
"MyTopicMyFuncSubscriptionEAF54A3F": {
"MyFuncMyTopicSubscription708A6535": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
Expand Down Expand Up @@ -368,7 +368,7 @@ export = {
"TopicName": "topicName"
}
},
"MyTopicMyQueueSubscription3245B11E": {
"MyQueueMyTopicSubscriptionEB66AD1B": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
Expand All @@ -383,7 +383,7 @@ export = {
}
}
},
"MyTopicMyFuncSubscriptionEAF54A3F": {
"MyFuncMyTopicSubscription708A6535": {
"Type": "AWS::SNS::Subscription",
"Properties": {
"Endpoint": {
Expand Down

0 comments on commit 0cc11ca

Please sign in to comment.