Skip to content

Commit

Permalink
feat(events): Add DLQ support for SQS target (aws#16916)
Browse files Browse the repository at this point in the history
feat(events-targets): Add DLQ support for SQS target

closes aws#16417 

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
ayush987goyal authored and TikiTDO committed Feb 21, 2022
1 parent bbe3ef5 commit 5e250d6
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-events-targets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ EventBridge.

## Event retry policy and using dead-letter queues

The Codebuild, CodePipeline, Lambda, StepFunctions and LogGroup targets support attaching a [dead letter queue and setting retry policies](https://docs.aws.amazon.com/eventbridge/latest/userguide/rule-dlq.html). See the [lambda example](#invoke-a-lambda-function).
The Codebuild, CodePipeline, Lambda, StepFunctions, LogGroup and SQSQueue targets support attaching a [dead letter queue and setting retry policies](https://docs.aws.amazon.com/eventbridge/latest/userguide/rule-dlq.html). See the [lambda example](#invoke-a-lambda-function).
Use [escape hatches](https://docs.aws.amazon.com/cdk/latest/guide/cfn_layer.html) for the other target types.

## Invoke a Lambda function
Expand Down
9 changes: 7 additions & 2 deletions packages/@aws-cdk/aws-events-targets/lib/sqs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import * as events from '@aws-cdk/aws-events';
import * as iam from '@aws-cdk/aws-iam';
import * as sqs from '@aws-cdk/aws-sqs';
import { addToDeadLetterQueueResourcePolicy, TargetBaseProps, bindBaseTargetConfig } from './util';

/**
* Customize the SQS Queue Event Target
*/
export interface SqsQueueProps {
export interface SqsQueueProps extends TargetBaseProps {

/**
* Message Group ID for messages sent to this queue
Expand All @@ -24,7 +25,6 @@ export interface SqsQueueProps {
* @default the entire EventBridge event
*/
readonly message?: events.RuleTargetInput;

}

/**
Expand Down Expand Up @@ -62,7 +62,12 @@ export class SqsQueue implements events.IRuleTarget {
// deduplicated automatically
this.queue.grantSendMessages(new iam.ServicePrincipal('events.amazonaws.com', principalOpts));

if (this.props.deadLetterQueue) {
addToDeadLetterQueueResourcePolicy(rule, this.props.deadLetterQueue);
}

return {
...bindBaseTargetConfig(this.props),
arn: this.queue.queueArn,
input: this.props.message,
targetResource: this.queue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@
"Arn"
]
},
"DeadLetterConfig": {
"Arn": {
"Fn::GetAtt": [
"MyDeadLetterQueueD997968A",
"Arn"
]
}
},
"Id": "Target0"
}
]
Expand Down Expand Up @@ -110,6 +118,50 @@
}
]
}
},
"MyDeadLetterQueueD997968A": {
"Type": "AWS::SQS::Queue",
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"MyDeadLetterQueuePolicyCC35D52C": {
"Type": "AWS::SQS::QueuePolicy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:SendMessage",
"Condition": {
"ArnEquals": {
"aws:SourceArn": {
"Fn::GetAtt": [
"MyRuleA44AB831",
"Arn"
]
}
}
},
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Resource": {
"Fn::GetAtt": [
"MyDeadLetterQueueD997968A",
"Arn"
]
},
"Sid": "AllowEventRuleawscdksqseventtargetMyRule0027A8F4"
}
],
"Version": "2012-10-17"
},
"Queues": [
{
"Ref": "MyDeadLetterQueueD997968A"
}
]
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ const queue = new sqs.Queue(stack, 'MyQueue', {
encryptionMasterKey: key,
});

event.addTarget(new targets.SqsQueue(queue));
const deadLetterQueue = new sqs.Queue(stack, 'MyDeadLetterQueue');

event.addTarget(new targets.SqsQueue(queue, {
deadLetterQueue,
}));

app.synth();
72 changes: 72 additions & 0 deletions packages/@aws-cdk/aws-events-targets/test/sqs/sqs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,75 @@ test('fifo queues are synthesized correctly', () => {
],
}));
});

test('dead letter queue is configured correctly', () => {
const stack = new Stack();
const queue = new sqs.Queue(stack, 'MyQueue', { fifo: true });
const deadLetterQueue = new sqs.Queue(stack, 'MyDeadLetterQueue');
const rule = new events.Rule(stack, 'MyRule', {
schedule: events.Schedule.rate(Duration.hours(1)),
});

// WHEN
rule.addTarget(new targets.SqsQueue(queue, {
deadLetterQueue,
}));

cdkExpect(stack).to(haveResource('AWS::Events::Rule', {
ScheduleExpression: 'rate(1 hour)',
State: 'ENABLED',
Targets: [
{
Arn: {
'Fn::GetAtt': [
'MyQueueE6CA6235',
'Arn',
],
},
Id: 'Target0',
DeadLetterConfig: {
Arn: {
'Fn::GetAtt': [
'MyDeadLetterQueueD997968A',
'Arn',
],
},
},
},
],
}));
});

test('specifying retry policy', () => {
const stack = new Stack();
const queue = new sqs.Queue(stack, 'MyQueue', { fifo: true });
const rule = new events.Rule(stack, 'MyRule', {
schedule: events.Schedule.rate(Duration.hours(1)),
});

// WHEN
rule.addTarget(new targets.SqsQueue(queue, {
retryAttempts: 2,
maxEventAge: Duration.hours(2),
}));

cdkExpect(stack).to(haveResource('AWS::Events::Rule', {
ScheduleExpression: 'rate(1 hour)',
State: 'ENABLED',
Targets: [
{
Arn: {
'Fn::GetAtt': [
'MyQueueE6CA6235',
'Arn',
],
},
Id: 'Target0',
RetryPolicy: {
MaximumEventAgeInSeconds: 7200,
MaximumRetryAttempts: 2,
},
},
],
}));
});

0 comments on commit 5e250d6

Please sign in to comment.