From #4237:
import * as cdk from "@aws-cdk/core";
import * as s3 from "@aws-cdk/aws-s3";
import * as lambda from "@aws-cdk/aws-lambda";
import * as cloudfront from "@aws-cdk/aws-cloudfront";
class SharedPwaLambdasStack extends cdk.Stack {
addCspHeadersFunction: lambda.Function;
constructor(scope: cdk.Construct, name: string, props?: cdk.StackProps) {
super(scope, name, props);
this.addCspHeadersFunction = new lambda.Function(this, "AddCspHeaders", {
runtime: lambda.Runtime.NODEJS_8_10,
handler: "index.handler",
code: lambda.Code.fromInline("irrelevant"),
});
}
}
interface PwaStackProps extends cdk.StackProps {
addCspHeadersFunction: lambda.Function;
}
class PwaStack extends cdk.Stack {
constructor(scope: cdk.Construct, name: string, props: PwaStackProps) {
super(scope, name, props);
const bucket = new s3.Bucket(this, `${name}Bucket`);
const distribution = new cloudfront.CloudFrontWebDistribution(this, `${name}Distribution`, {
originConfigs: [
{
s3OriginSource: {
s3BucketSource: bucket,
},
behaviors: [
{
isDefaultBehavior: true,
lambdaFunctionAssociations: [
{
eventType: cloudfront.LambdaEdgeEventType.VIEWER_RESPONSE,
lambdaFunction: props.addCspHeadersFunction.latestVersion,
},
],
},
],
},
],
});
}
}
const app = new cdk.App();
const sharedPwaLambdasStack = new SharedPwaLambdasStack(app, "SharedPwaLambdas");
const websitePwa = new PwaStack(app, "WebsitePwa", {
addCspHeadersFunction: sharedPwaLambdasStack.addCspHeadersFunction,
});
// If you comment the following stack, it will work.
const adminPwa = new PwaStack(app, "AdminPwa", {
addCspHeadersFunction: sharedPwaLambdasStack.addCspHeadersFunction,
});
cdk synth
yarn run v1.19.0
$ /code/node_modules/.bin/ts-node index.ts
/code/node_modules/@aws-cdk/core/lib/construct.ts:512
throw new Error(`There is already a Construct with name '${childName}' in ${typeName}${name.length > 0 ? ' [' + name + ']' : ''}`);
^
Error: There is already a Construct with name '$LATEST' in Function [AddCspHeaders]
at ConstructNode.addChild (/code/node_modules/@aws-cdk/core/lib/construct.ts:512:13)
at new ConstructNode (/code/node_modules/@aws-cdk/core/lib/construct.ts:144:18)
at new Construct (/code/node_modules/@aws-cdk/core/lib/construct.ts:563:17)
at new Resource (/code/node_modules/@aws-cdk/core/lib/resource.ts:61:5)
at new FunctionBase (/code/node_modules/@aws-cdk/aws-lambda/lib/function-base.ts:139:1)
at new LatestVersion (/code/node_modules/@aws-cdk/aws-lambda/lib/function-base.ts:336:5)
at Function.get latestVersion [as latestVersion] (/code/node_modules/@aws-cdk/aws-lambda/lib/function-base.ts:233:12)
at new PwaStack (/code/cloud/index.ts:42:63)
at Object.<anonymous> (/code/cloud/index.ts:62:18)
at Module._compile (internal/modules/cjs/loader.js:936:30)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
This is :bug: Bug Report
cc @skyrpex
Is there a workaround for this?
Is there a workaround for this?
You can create as many lambdas as CloudFront distributions you got.
I believe the problem is with the dual reference to props.addCspHeadersFunction.latestVersion, which creates multiple instances, with the same scope and id:
A workaround could be storing the latest version in a const, and passing an IVersion, instead of a Function:
const sharedPwaLambdasStack = new SharedPwaLambdasStack(app, "SharedPwaLambdas");
const latestVersion = sharedPwaLambdasStack.addCspHeadersFunction.latestVersion;
const websitePwa = new PwaStack(app, "WebsitePwa", {
addCspHeadersFunctionVersion: latestVersion,
});
// If you comment the following stack, it will work.
const adminPwa = new PwaStack(app, "AdminPwa", {
addCspHeadersFunctionVersion: latestVersion,
});