Skip to content

Commit

Permalink
feat(sns): adding support for firehose subscription protocol (#15764)
Browse files Browse the repository at this point in the history
This PR adds support for the firehose subscription protocol by extending the protocol enum and by requiring the field "subscriptionRoleArn" if the protocol is set to firehose.

This is so that users can take advantage of the new SNS-to-Firehose integration introduced in February 2021 (see [here](https://aws.amazon.com/blogs/compute/introducing-message-archiving-and-analytics-for-amazon-sns/) for the announcement).

Here also is a link to the [sample cloudformation](https://docs.aws.amazon.com/sns/latest/dg/firehose-example-cfn.html), documenting the SNS-to-Firehose integration.

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
david-doyle-as24 authored Sep 10, 2021
1 parent 38426c9 commit 18aff6b
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 10 deletions.
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-sns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,20 @@ topic.addSubscription(new subs.LambdaSubscription(fn, {
}));
```

### Example of Firehose Subscription

```typescript
import { Subscription, SubscriptionProtocol, Topic } from '@aws-cdk/aws-sns';
import { DeliveryStream } from '@aws-cdk/aws-kinesisfirehose';
const topic = new Topic(stack, 'Topic');
const stream = new DeliveryStream(stack, 'DeliveryStream', ...)
new Subscription(stack, 'Subscription', {
endpoint: stream.deliveryStreamArn,
protocol: SubscriptionProtocol.FIREHOSE,
subscriptionRoleArn: "SAMPLE_ARN", //role with permissions to send messages to a firehose delivery stream
})
```

## DLQ setup for SNS Subscription

CDK can attach provided Queue as DLQ for your SNS subscription.
Expand Down
30 changes: 27 additions & 3 deletions packages/@aws-cdk/aws-sns/lib/subscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ export interface SubscriptionOptions {
* @default - No dead letter queue enabled.
*/
readonly deadLetterQueue?: IQueue;

/**
* Arn of role allowing access to firehose delivery stream.
* Required for a firehose subscription protocol.
* @default - No subscription role is provided
*/
readonly subscriptionRoleArn?: string;
}
/**
* Properties for creating a new subscription
Expand Down Expand Up @@ -81,8 +88,15 @@ export class Subscription extends Resource {
constructor(scope: Construct, id: string, props: SubscriptionProps) {
super(scope, id);

if (props.rawMessageDelivery && ['http', 'https', 'sqs'].indexOf(props.protocol) < 0) {
throw new Error('Raw message delivery can only be enabled for HTTP/S and SQS subscriptions.');
if (props.rawMessageDelivery &&
[
SubscriptionProtocol.HTTP,
SubscriptionProtocol.HTTPS,
SubscriptionProtocol.SQS,
SubscriptionProtocol.FIREHOSE,
]
.indexOf(props.protocol) < 0) {
throw new Error('Raw message delivery can only be enabled for HTTP, HTTPS, SQS, and Firehose subscriptions.');
}

if (props.filterPolicy) {
Expand All @@ -103,6 +117,10 @@ export class Subscription extends Resource {
}
}

if (props.protocol === SubscriptionProtocol.FIREHOSE && !props.subscriptionRoleArn) {
throw new Error('Subscription role arn is required field for subscriptions with a firehose protocol.');
}

this.deadLetterQueue = this.buildDeadLetterQueue(props);

new CfnSubscription(this, 'Resource', {
Expand All @@ -113,6 +131,7 @@ export class Subscription extends Resource {
filterPolicy: this.filterPolicy,
region: props.region,
redrivePolicy: this.buildDeadLetterConfig(this.deadLetterQueue),
subscriptionRoleArn: props.subscriptionRoleArn,
});

}
Expand Down Expand Up @@ -189,5 +208,10 @@ export enum SubscriptionProtocol {
/**
* Notifications trigger a Lambda function.
*/
LAMBDA = 'lambda'
LAMBDA = 'lambda',

/**
* Notifications put records into a firehose delivery stream.
*/
FIREHOSE = 'firehose'
}
6 changes: 3 additions & 3 deletions packages/@aws-cdk/aws-sns/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@
},
"license": "Apache-2.0",
"devDependencies": {
"@aws-cdk/aws-s3": "0.0.0",
"@aws-cdk/assertions": "0.0.0",
"@aws-cdk/aws-s3": "0.0.0",
"@types/jest": "^26.0.24",
"cdk-build-tools": "0.0.0",
"cdk-integ-tools": "0.0.0",
Expand All @@ -86,8 +86,8 @@
"pkglint": "0.0.0"
},
"dependencies": {
"@aws-cdk/aws-codestarnotifications": "0.0.0",
"@aws-cdk/aws-cloudwatch": "0.0.0",
"@aws-cdk/aws-codestarnotifications": "0.0.0",
"@aws-cdk/aws-events": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/aws-kms": "0.0.0",
Expand All @@ -97,8 +97,8 @@
},
"homepage": "https://github.com/aws/aws-cdk",
"peerDependencies": {
"@aws-cdk/aws-codestarnotifications": "0.0.0",
"@aws-cdk/aws-cloudwatch": "0.0.0",
"@aws-cdk/aws-codestarnotifications": "0.0.0",
"@aws-cdk/aws-events": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/aws-kms": "0.0.0",
Expand Down
29 changes: 25 additions & 4 deletions packages/@aws-cdk/aws-sns/test/subscription.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Template } from '@aws-cdk/assertions';
import { Queue } from '@aws-cdk/aws-sqs';
import * as cdk from '@aws-cdk/core';
import * as sns from '../lib';
import { SubscriptionProtocol } from '../lib';

describe('Subscription', () => {
test('create a subscription', () => {
Expand Down Expand Up @@ -176,19 +177,26 @@ describe('Subscription', () => {

});

test('throws with raw delivery for protocol other than http, https or sqs', () => {

test.each(
[
SubscriptionProtocol.LAMBDA,
SubscriptionProtocol.EMAIL,
SubscriptionProtocol.EMAIL_JSON,
SubscriptionProtocol.SMS,
SubscriptionProtocol.APPLICATION,
])
('throws with raw delivery for %s protocol', (protocol: SubscriptionProtocol) => {
// GIVEN
const stack = new cdk.Stack();
const topic = new sns.Topic(stack, 'Topic');

// THEN
expect(() => new sns.Subscription(stack, 'Subscription', {
endpoint: 'endpoint',
protocol: sns.SubscriptionProtocol.LAMBDA,
protocol: protocol,
topic,
rawMessageDelivery: true,
})).toThrow(/Raw message delivery/);

});

test('throws with more than 5 attributes in a filter policy', () => {
Expand Down Expand Up @@ -232,4 +240,17 @@ describe('Subscription', () => {
})).toThrow(/\(120\) must not exceed 100/);

});

test('throws an error when subscription role arn is not entered with firehose subscription protocol', () => {
// GIVEN
const stack = new cdk.Stack();
const topic = new sns.Topic(stack, 'Topic');

//THEN
expect(() => new sns.Subscription(stack, 'Subscription', {
endpoint: 'endpoint',
protocol: sns.SubscriptionProtocol.FIREHOSE,
topic,
})).toThrow(/Subscription role arn is required field for subscriptions with a firehose protocol./);
});
});

0 comments on commit 18aff6b

Please sign in to comment.