Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
},
},
],
}));
});