Skip to content

Commit 1fb2c04

Browse files
author
Niranjan Jayakar
committed
fix(lambda): cannot use latest version in multiple CloudFront distributions
The error produced is around construct collision, i.e., "There is already a Construct with name '$LATEST' in Function". The fix is to cache the latest version on the instance. fixes #4459
1 parent 1c9b733 commit 1fb2c04

File tree

3 files changed

+72
-6
lines changed

3 files changed

+72
-6
lines changed

packages/@aws-cdk/aws-lambda/lib/event-invoke-config.ts

+41-5
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@ import { CfnEventInvokeConfig } from './lambda.generated';
55

66
/**
77
* Options to add an EventInvokeConfig to a function.
8+
* @deprecated - use `new EventInvokeConfig()` instead
89
*/
910
export interface EventInvokeConfigOptions {
1011
/**
1112
* The destination for failed invocations.
12-
*
13+
* @deprecated use `new EventInvokeConfig()` instead to define a new event invoke configuration
1314
* @default - no destination
1415
*/
1516
readonly onFailure?: IDestination;
1617

1718
/**
1819
* The destination for successful invocations.
19-
*
20+
* @deprecated use `new EventInvokeConfig()` instead to define a new event invoke configuration
2021
* @default - no destination
2122
*/
2223
readonly onSuccess?: IDestination;
@@ -27,7 +28,7 @@ export interface EventInvokeConfigOptions {
2728
*
2829
* Minimum: 60 seconds
2930
* Maximum: 6 hours
30-
*
31+
* @deprecated use `new EventInvokeConfig()` instead to define a new event invoke configuration
3132
* @default Duration.hours(6)
3233
*/
3334
readonly maxEventAge?: Duration;
@@ -37,7 +38,7 @@ export interface EventInvokeConfigOptions {
3738
*
3839
* Minimum: 0
3940
* Maximum: 2
40-
*
41+
* @deprecated use `new EventInvokeConfig()` instead to define a new event invoke configuration
4142
* @default 2
4243
*/
4344
readonly retryAttempts?: number;
@@ -46,7 +47,7 @@ export interface EventInvokeConfigOptions {
4647
/**
4748
* Properties for an EventInvokeConfig
4849
*/
49-
export interface EventInvokeConfigProps extends EventInvokeConfigOptions {
50+
export interface EventInvokeConfigProps {
5051
/**
5152
* The Lambda function
5253
*/
@@ -58,6 +59,41 @@ export interface EventInvokeConfigProps extends EventInvokeConfigOptions {
5859
* @default - latest version
5960
*/
6061
readonly qualifier?: string;
62+
63+
/**
64+
* The destination for failed invocations.
65+
*
66+
* @default - no destination
67+
*/
68+
readonly onFailure?: IDestination;
69+
70+
/**
71+
* The destination for successful invocations.
72+
*
73+
* @default - no destination
74+
*/
75+
readonly onSuccess?: IDestination;
76+
77+
/**
78+
* The maximum age of a request that Lambda sends to a function for
79+
* processing.
80+
*
81+
* Minimum: 60 seconds
82+
* Maximum: 6 hours
83+
*
84+
* @default Duration.hours(6)
85+
*/
86+
readonly maxEventAge?: Duration;
87+
88+
/**
89+
* The maximum number of times to retry when the function returns an error.
90+
*
91+
* Minimum: 0
92+
* Maximum: 2
93+
*
94+
* @default 2
95+
*/
96+
readonly retryAttempts?: number;
6197
}
6298

6399
/**

packages/@aws-cdk/aws-lambda/lib/function-base.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ export abstract class FunctionBase extends Resource implements IFunction {
194194
*/
195195
protected _connections?: ec2.Connections;
196196

197+
private _latestVersion?: LatestVersion;
198+
197199
/**
198200
* Adds a permission to the Lambda resource policy.
199201
* @param id The id ƒor the permission construct
@@ -245,7 +247,10 @@ export abstract class FunctionBase extends Resource implements IFunction {
245247

246248
public get latestVersion(): IVersion {
247249
// Dynamic to avoid infinite recursion when creating the LatestVersion instance...
248-
return new LatestVersion(this);
250+
if (!this._latestVersion) {
251+
this._latestVersion = new LatestVersion(this);
252+
}
253+
return this._latestVersion;
249254
}
250255

251256
/**

packages/@aws-cdk/aws-lambda/test/test.function.ts

+25
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,31 @@ export = testCase({
359359
test.done();
360360
},
361361

362+
'multiple calls to latestVersion returns the same version'(test: Test) {
363+
const stack = new cdk.Stack();
364+
365+
const fn = new lambda.Function(stack, 'MyLambda', {
366+
code: new lambda.InlineCode('hello()'),
367+
handler: 'index.hello',
368+
runtime: lambda.Runtime.NODEJS_10_X,
369+
});
370+
371+
const version1 = fn.latestVersion;
372+
const version2 = fn.latestVersion;
373+
374+
const expectedArn = {
375+
'Fn::Join': ['', [
376+
{ 'Fn::GetAtt': ['MyLambdaCCE802FB', 'Arn'] },
377+
':$LATEST',
378+
]],
379+
};
380+
test.equal(version1, version2);
381+
test.deepEqual(stack.resolve(version1.functionArn), expectedArn);
382+
test.deepEqual(stack.resolve(version2.functionArn), expectedArn);
383+
384+
test.done();
385+
},
386+
362387
'currentVersion': {
363388
// see test.function-hash.ts for more coverage for this
364389
'logical id of version is based on the function hash'(test: Test) {

0 commit comments

Comments
 (0)