Skip to content

Commit 7fda903

Browse files
feat(events): Add DLQ support for SQS target (#16916)
feat(events-targets): Add DLQ support for SQS target closes #16417 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent b3c00c0 commit 7fda903

File tree

5 files changed

+137
-4
lines changed

5 files changed

+137
-4
lines changed

packages/@aws-cdk/aws-events-targets/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ EventBridge.
3535

3636
## Event retry policy and using dead-letter queues
3737

38-
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).
38+
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).
3939
Use [escape hatches](https://docs.aws.amazon.com/cdk/latest/guide/cfn_layer.html) for the other target types.
4040

4141
## Invoke a Lambda function

packages/@aws-cdk/aws-events-targets/lib/sqs.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import * as events from '@aws-cdk/aws-events';
22
import * as iam from '@aws-cdk/aws-iam';
33
import * as sqs from '@aws-cdk/aws-sqs';
4+
import { addToDeadLetterQueueResourcePolicy, TargetBaseProps, bindBaseTargetConfig } from './util';
45

56
/**
67
* Customize the SQS Queue Event Target
78
*/
8-
export interface SqsQueueProps {
9+
export interface SqsQueueProps extends TargetBaseProps {
910

1011
/**
1112
* Message Group ID for messages sent to this queue
@@ -24,7 +25,6 @@ export interface SqsQueueProps {
2425
* @default the entire EventBridge event
2526
*/
2627
readonly message?: events.RuleTargetInput;
27-
2828
}
2929

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

65+
if (this.props.deadLetterQueue) {
66+
addToDeadLetterQueueResourcePolicy(rule, this.props.deadLetterQueue);
67+
}
68+
6569
return {
70+
...bindBaseTargetConfig(this.props),
6671
arn: this.queue.queueArn,
6772
input: this.props.message,
6873
targetResource: this.queue,

packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.expected.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@
6161
"Arn"
6262
]
6363
},
64+
"DeadLetterConfig": {
65+
"Arn": {
66+
"Fn::GetAtt": [
67+
"MyDeadLetterQueueD997968A",
68+
"Arn"
69+
]
70+
}
71+
},
6472
"Id": "Target0"
6573
}
6674
]
@@ -110,6 +118,50 @@
110118
}
111119
]
112120
}
121+
},
122+
"MyDeadLetterQueueD997968A": {
123+
"Type": "AWS::SQS::Queue",
124+
"UpdateReplacePolicy": "Delete",
125+
"DeletionPolicy": "Delete"
126+
},
127+
"MyDeadLetterQueuePolicyCC35D52C": {
128+
"Type": "AWS::SQS::QueuePolicy",
129+
"Properties": {
130+
"PolicyDocument": {
131+
"Statement": [
132+
{
133+
"Action": "sqs:SendMessage",
134+
"Condition": {
135+
"ArnEquals": {
136+
"aws:SourceArn": {
137+
"Fn::GetAtt": [
138+
"MyRuleA44AB831",
139+
"Arn"
140+
]
141+
}
142+
}
143+
},
144+
"Effect": "Allow",
145+
"Principal": {
146+
"Service": "events.amazonaws.com"
147+
},
148+
"Resource": {
149+
"Fn::GetAtt": [
150+
"MyDeadLetterQueueD997968A",
151+
"Arn"
152+
]
153+
},
154+
"Sid": "AllowEventRuleawscdksqseventtargetMyRule0027A8F4"
155+
}
156+
],
157+
"Version": "2012-10-17"
158+
},
159+
"Queues": [
160+
{
161+
"Ref": "MyDeadLetterQueueD997968A"
162+
}
163+
]
164+
}
113165
}
114166
}
115167
}

packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ const queue = new sqs.Queue(stack, 'MyQueue', {
2424
encryptionMasterKey: key,
2525
});
2626

27-
event.addTarget(new targets.SqsQueue(queue));
27+
const deadLetterQueue = new sqs.Queue(stack, 'MyDeadLetterQueue');
28+
29+
event.addTarget(new targets.SqsQueue(queue, {
30+
deadLetterQueue,
31+
}));
2832

2933
app.synth();

packages/@aws-cdk/aws-events-targets/test/sqs/sqs.test.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,75 @@ test('fifo queues are synthesized correctly', () => {
180180
],
181181
}));
182182
});
183+
184+
test('dead letter queue is configured correctly', () => {
185+
const stack = new Stack();
186+
const queue = new sqs.Queue(stack, 'MyQueue', { fifo: true });
187+
const deadLetterQueue = new sqs.Queue(stack, 'MyDeadLetterQueue');
188+
const rule = new events.Rule(stack, 'MyRule', {
189+
schedule: events.Schedule.rate(Duration.hours(1)),
190+
});
191+
192+
// WHEN
193+
rule.addTarget(new targets.SqsQueue(queue, {
194+
deadLetterQueue,
195+
}));
196+
197+
cdkExpect(stack).to(haveResource('AWS::Events::Rule', {
198+
ScheduleExpression: 'rate(1 hour)',
199+
State: 'ENABLED',
200+
Targets: [
201+
{
202+
Arn: {
203+
'Fn::GetAtt': [
204+
'MyQueueE6CA6235',
205+
'Arn',
206+
],
207+
},
208+
Id: 'Target0',
209+
DeadLetterConfig: {
210+
Arn: {
211+
'Fn::GetAtt': [
212+
'MyDeadLetterQueueD997968A',
213+
'Arn',
214+
],
215+
},
216+
},
217+
},
218+
],
219+
}));
220+
});
221+
222+
test('specifying retry policy', () => {
223+
const stack = new Stack();
224+
const queue = new sqs.Queue(stack, 'MyQueue', { fifo: true });
225+
const rule = new events.Rule(stack, 'MyRule', {
226+
schedule: events.Schedule.rate(Duration.hours(1)),
227+
});
228+
229+
// WHEN
230+
rule.addTarget(new targets.SqsQueue(queue, {
231+
retryAttempts: 2,
232+
maxEventAge: Duration.hours(2),
233+
}));
234+
235+
cdkExpect(stack).to(haveResource('AWS::Events::Rule', {
236+
ScheduleExpression: 'rate(1 hour)',
237+
State: 'ENABLED',
238+
Targets: [
239+
{
240+
Arn: {
241+
'Fn::GetAtt': [
242+
'MyQueueE6CA6235',
243+
'Arn',
244+
],
245+
},
246+
Id: 'Target0',
247+
RetryPolicy: {
248+
MaximumEventAgeInSeconds: 7200,
249+
MaximumRetryAttempts: 2,
250+
},
251+
},
252+
],
253+
}));
254+
});

0 commit comments

Comments
 (0)