diff --git a/packages/@aws-cdk/aws-sns/README.md b/packages/@aws-cdk/aws-sns/README.md index ab7120411df39..23ee15e4af508 100644 --- a/packages/@aws-cdk/aws-sns/README.md +++ b/packages/@aws-cdk/aws-sns/README.md @@ -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. diff --git a/packages/@aws-cdk/aws-sns/lib/subscription.ts b/packages/@aws-cdk/aws-sns/lib/subscription.ts index 88817b6db6fdd..54e26cd24eb60 100644 --- a/packages/@aws-cdk/aws-sns/lib/subscription.ts +++ b/packages/@aws-cdk/aws-sns/lib/subscription.ts @@ -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 @@ -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) { @@ -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', { @@ -113,6 +131,7 @@ export class Subscription extends Resource { filterPolicy: this.filterPolicy, region: props.region, redrivePolicy: this.buildDeadLetterConfig(this.deadLetterQueue), + subscriptionRoleArn: props.subscriptionRoleArn, }); } @@ -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' } diff --git a/packages/@aws-cdk/aws-sns/package.json b/packages/@aws-cdk/aws-sns/package.json index c7734d512cdfd..26d7441d5ee6d 100644 --- a/packages/@aws-cdk/aws-sns/package.json +++ b/packages/@aws-cdk/aws-sns/package.json @@ -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", @@ -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", @@ -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", diff --git a/packages/@aws-cdk/aws-sns/test/subscription.test.ts b/packages/@aws-cdk/aws-sns/test/subscription.test.ts index 0c19eddc0c7d5..a495769648d4b 100644 --- a/packages/@aws-cdk/aws-sns/test/subscription.test.ts +++ b/packages/@aws-cdk/aws-sns/test/subscription.test.ts @@ -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', () => { @@ -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', () => { @@ -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./); + }); });