Skip to content

Commit

Permalink
fix(cloudfront): cannot add two EdgeFunctions with same aliases (#13324)
Browse files Browse the repository at this point in the history
Attempting to add two EdgeFunctions to the same stack, and then giving both the
same alias (e.g., 'prod', 'live') results in an ID conflict. This is because the
aliases are being added to the scope of the shared EdgeFunction stack, rather
than the scope of the Function itself.

Note - Also took the opportunity to simplify one of the integ tests to deploy to a
single distribution.

fixes #13237


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
njlynch authored Mar 1, 2021
1 parent c366837 commit 1f35351
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,17 @@ export class EdgeFunction extends Resource implements lambda.IVersion {
public readonly role?: iam.IRole;
public readonly version: string;

// functionStack needed for `addAlias`.
private readonly functionStack: Stack;
private readonly _edgeFunction: lambda.Function;

constructor(scope: Construct, id: string, props: EdgeFunctionProps) {
super(scope, id);

// Create a simple Function if we're already in us-east-1; otherwise create a cross-region stack.
const regionIsUsEast1 = !Token.isUnresolved(this.stack.region) && this.stack.region === 'us-east-1';
const { functionStack, edgeFunction, edgeArn } = regionIsUsEast1
const { edgeFunction, edgeArn } = regionIsUsEast1
? this.createInRegionFunction(props)
: this.createCrossRegionFunction(id, props);

this.functionStack = functionStack;
this.edgeArn = edgeArn;

this.functionArn = edgeArn;
Expand All @@ -89,7 +86,7 @@ export class EdgeFunction extends Resource implements lambda.IVersion {
}

public addAlias(aliasName: string, options: lambda.AliasOptions = {}): lambda.Alias {
return new lambda.Alias(this.functionStack, `Alias${aliasName}`, {
return new lambda.Alias(this._edgeFunction, `Alias${aliasName}`, {
aliasName,
version: this._edgeFunction.currentVersion,
...options,
Expand Down Expand Up @@ -146,7 +143,7 @@ export class EdgeFunction extends Resource implements lambda.IVersion {
const edgeFunction = new lambda.Function(this, 'Fn', props);
addEdgeLambdaToRoleTrustStatement(edgeFunction.role!);

return { edgeFunction, edgeArn: edgeFunction.currentVersion.edgeArn, functionStack: this.stack };
return { edgeFunction, edgeArn: edgeFunction.currentVersion.edgeArn };
}

/** Create a support stack and function in us-east-1, and a SSM reader in-region */
Expand All @@ -166,7 +163,7 @@ export class EdgeFunction extends Resource implements lambda.IVersion {

const edgeArn = this.createCrossRegionArnReader(parameterNamePrefix, parameterName, edgeFunction);

return { edgeFunction, edgeArn, functionStack };
return { edgeFunction, edgeArn };
}

private createCrossRegionArnReader(parameterNamePrefix: string, parameterName: string, edgeFunction: lambda.Function): string {
Expand Down Expand Up @@ -233,7 +230,6 @@ export class EdgeFunction extends Resource implements lambda.IVersion {
interface FunctionConfig {
readonly edgeFunction: lambda.Function;
readonly edgeArn: string;
readonly functionStack: Stack;
}

function addEdgeLambdaToRoleTrustStatement(role: iam.IRole) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,17 @@ test('addAlias() creates alias in function stack', () => {
});
});

test('mutliple aliases with the same name can be added to the same stack', () => {
const fn1 = new cloudfront.experimental.EdgeFunction(stack, 'MyFn1', defaultEdgeFunctionProps());
const fn2 = new cloudfront.experimental.EdgeFunction(stack, 'MyFn2', defaultEdgeFunctionProps());
fn1.addAlias('live');
fn2.addAlias('live');

const fnStack = getFnStack();
expect(fnStack).toCountResources('AWS::Lambda::Function', 2);
expect(fnStack).toCountResources('AWS::Lambda::Alias', 2);
});

test('addPermission() creates permissions in function stack', () => {
const fn = new cloudfront.experimental.EdgeFunction(stack, 'MyFn', defaultEdgeFunctionProps());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,36 +159,9 @@
"FunctionArn"
]
}
}
],
"TargetOriginId": "integdistributionlambdacrossregionDistOrigin167A054D5",
"ViewerProtocolPolicy": "allow-all"
},
"Enabled": true,
"HttpVersion": "http2",
"IPV6Enabled": true,
"Origins": [
{
"CustomOriginConfig": {
"OriginProtocolPolicy": "https-only"
},
"DomainName": "www.example.com",
"Id": "integdistributionlambdacrossregionDistOrigin167A054D5"
}
]
}
}
},
"Dist286EC08DF": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"DefaultCacheBehavior": {
"CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad",
"Compress": true,
"LambdaFunctionAssociations": [
{
"EventType": "origin-request",
"EventType": "origin-response",
"LambdaFunctionARN": {
"Fn::GetAtt": [
"Lambda2ArnReader5ACFBE1F",
Expand All @@ -197,7 +170,7 @@
}
}
],
"TargetOriginId": "integdistributionlambdacrossregionDist2Origin14F08376D",
"TargetOriginId": "integdistributionlambdacrossregionDistOrigin167A054D5",
"ViewerProtocolPolicy": "allow-all"
},
"Enabled": true,
Expand All @@ -208,8 +181,8 @@
"CustomOriginConfig": {
"OriginProtocolPolicy": "https-only"
},
"DomainName": "www.example2.com",
"Id": "integdistributionlambdacrossregionDist2Origin14F08376D"
"DomainName": "www.example.com",
"Id": "integdistributionlambdacrossregionDistOrigin167A054D5"
}
]
}
Expand Down Expand Up @@ -277,13 +250,13 @@
"Code": {
"ZipFile": "foo"
},
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"LambdaServiceRoleA8ED4D3B",
"Arn"
]
},
"Handler": "index.handler",
"Runtime": "nodejs10.x"
},
"DependsOn": [
Expand All @@ -307,6 +280,21 @@
},
"Name": "EdgeFunctionArnLambda"
}
},
"LambdaAliaslive79C8A712": {
"Type": "AWS::Lambda::Alias",
"Properties": {
"FunctionName": {
"Ref": "LambdaD247545B"
},
"FunctionVersion": {
"Fn::GetAtt": [
"LambdaCurrentVersionDF706F6A97fb843e9bd06fcd2bb15eeace80e13e",
"Version"
]
},
"Name": "live"
}
}
}
},
Expand Down Expand Up @@ -356,13 +344,13 @@
"Code": {
"ZipFile": "foo"
},
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"Lambda2ServiceRole31A072E1",
"Arn"
]
},
"Handler": "index.handler",
"Runtime": "nodejs10.x"
},
"DependsOn": [
Expand All @@ -386,6 +374,21 @@
},
"Name": "EdgeFunctionArnLambda2"
}
},
"Lambda2Aliaslive77F6085F": {
"Type": "AWS::Lambda::Alias",
"Properties": {
"FunctionName": {
"Ref": "Lambda217CFB423"
},
"FunctionVersion": {
"Fn::GetAtt": [
"Lambda2CurrentVersion72012B74b9eef8becb98501bc795baca3c6169c4",
"Version"
]
},
"Name": "live"
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,23 @@ const lambdaFunction2 = new cloudfront.experimental.EdgeFunction(stack, 'Lambda2
stackId: `edge-lambda-stack-${region}-2`,
});

lambdaFunction.addAlias('live');
lambdaFunction2.addAlias('live');

new cloudfront.Distribution(stack, 'Dist', {
defaultBehavior: {
origin: new TestOrigin('www.example.com'),
cachePolicy: cloudfront.CachePolicy.CACHING_DISABLED,
edgeLambdas: [{
functionVersion: lambdaFunction.currentVersion,
eventType: cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
}],
},
});

new cloudfront.Distribution(stack, 'Dist2', {
defaultBehavior: {
origin: new TestOrigin('www.example2.com'),
cachePolicy: cloudfront.CachePolicy.CACHING_DISABLED,
edgeLambdas: [{
functionVersion: lambdaFunction2.currentVersion,
eventType: cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
}],
edgeLambdas: [
{
functionVersion: lambdaFunction.currentVersion,
eventType: cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
},
{
functionVersion: lambdaFunction2.currentVersion,
eventType: cloudfront.LambdaEdgeEventType.ORIGIN_RESPONSE,
},
],
},
});

Expand Down

0 comments on commit 1f35351

Please sign in to comment.