diff --git a/packages/@aws-cdk/aws-lambda/lib/function.ts b/packages/@aws-cdk/aws-lambda/lib/function.ts index db0c922ef6bba..2b76f8a21bd80 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function.ts @@ -407,6 +407,11 @@ export class Function extends FunctionBase { */ public readonly grantPrincipal: iam.IPrincipal; + /** + * The DLQ associated with this Lambda Function (this is an optional attribute). + */ + public readonly deadLetterQueue?: sqs.IQueue; + public readonly permissionsNode = this.node; protected readonly canCreatePermissions = true; @@ -450,6 +455,8 @@ export class Function extends FunctionBase { const code = props.code.bind(this); verifyCodeConfig(code, props.runtime); + this.deadLetterQueue = this.buildDeadLetterQueue(props); + const resource: CfnFunction = new CfnFunction(this, 'Resource', { functionName: this.physicalName, description: props.description, @@ -467,7 +474,7 @@ export class Function extends FunctionBase { environment: Lazy.anyValue({ produce: () => this.renderEnvironment() }), memorySize: props.memorySize, vpcConfig: this.configureVpc(props), - deadLetterConfig: this.buildDeadLetterConfig(props), + deadLetterConfig: this.buildDeadLetterConfig(this.deadLetterQueue), tracingConfig: this.buildTracingConfig(props), reservedConcurrentExecutions: props.reservedConcurrentExecutions }); @@ -668,7 +675,7 @@ export class Function extends FunctionBase { }; } - private buildDeadLetterConfig(props: FunctionProps) { + private buildDeadLetterQueue(props: FunctionProps) { if (props.deadLetterQueue && props.deadLetterQueueEnabled === false) { throw Error('deadLetterQueue defined but deadLetterQueueEnabled explicitly set to false'); } @@ -686,9 +693,17 @@ export class Function extends FunctionBase { resources: [deadLetterQueue.queueArn] })); - return { - targetArn: deadLetterQueue.queueArn - }; + return deadLetterQueue; + } + + private buildDeadLetterConfig(deadLetterQueue?: sqs.IQueue) { + if (deadLetterQueue) { + return { + targetArn: deadLetterQueue.queueArn + }; + } else { + return undefined; + } } private buildTracingConfig(props: FunctionProps) { diff --git a/packages/@aws-cdk/aws-lambda/test/test.function.ts b/packages/@aws-cdk/aws-lambda/test/test.function.ts index 5134a5fc69287..cfe793480b997 100644 --- a/packages/@aws-cdk/aws-lambda/test/test.function.ts +++ b/packages/@aws-cdk/aws-lambda/test/test.function.ts @@ -1,5 +1,6 @@ import * as logs from '@aws-cdk/aws-logs'; import * as s3 from '@aws-cdk/aws-s3'; +import * as sqs from '@aws-cdk/aws-sqs'; import * as cdk from '@aws-cdk/core'; import * as _ from 'lodash'; import {Test, testCase} from 'nodeunit'; @@ -101,6 +102,54 @@ export = testCase({ test.done(); }, + 'dlq is returned when provided by user'(test: Test) { + const stack = new cdk.Stack(); + + const dlQueue = new sqs.Queue(stack, 'DeadLetterQueue', { + queueName: 'MyLambda_DLQ', + retentionPeriod: cdk.Duration.days(14) + }); + + const fn = new lambda.Function(stack, 'fn', { + handler: 'foo', + runtime: lambda.Runtime.NODEJS_10_X, + code: lambda.Code.fromInline('foo'), + deadLetterQueue: dlQueue, + }); + const deadLetterQueue = fn.deadLetterQueue; + test.ok(deadLetterQueue?.queueArn); + test.ok(deadLetterQueue?.queueName); + test.ok(deadLetterQueue?.queueUrl); + test.done(); + }, + + 'dlq is returned when setup by cdk'(test: Test) { + const stack = new cdk.Stack(); + const fn = new lambda.Function(stack, 'fn', { + handler: 'foo', + runtime: lambda.Runtime.NODEJS_10_X, + code: lambda.Code.fromInline('foo'), + deadLetterQueueEnabled: true, + }); + const deadLetterQueue = fn.deadLetterQueue; + test.ok(deadLetterQueue?.queueArn); + test.ok(deadLetterQueue?.queueName); + test.ok(deadLetterQueue?.queueUrl); + test.done(); + }, + + 'dlq is undefined when not setup'(test: Test) { + const stack = new cdk.Stack(); + const fn = new lambda.Function(stack, 'fn', { + handler: 'foo', + runtime: lambda.Runtime.NODEJS_10_X, + code: lambda.Code.fromInline('foo'), + }); + const deadLetterQueue = fn.deadLetterQueue; + test.ok(deadLetterQueue === undefined); + test.done(); + }, + 'one and only one child LogRetention construct will be created'(test: Test) { const stack = new cdk.Stack(); const fn = new lambda.Function(stack, 'fn', {