Skip to content

Commit

Permalink
fix(cloudfront): EdgeFunction fails with newStyleStackSynthesis
Browse files Browse the repository at this point in the history
The EdgeFunction construct copied some patterns from CodePipelines to enable
cross-environment interaction. One key difference is that for Lambda@Edge,
CDK assets are created in the cross-environment support stack. This isn't
supported by the BootstraplessSynthesizer, so this custom logic (copied from
CodePipelines) needs to be removed.

The EdgeFunction support stack will now use whatever synthesizer is default for
the current stack.

fixes #12172
  • Loading branch information
njlynch committed Jan 5, 2021
1 parent b1996cd commit b63172f
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
20 changes: 2 additions & 18 deletions packages/@aws-cdk/aws-cloudfront/lib/experimental/edge-function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import * as iam from '@aws-cdk/aws-iam';
import * as lambda from '@aws-cdk/aws-lambda';
import * as ssm from '@aws-cdk/aws-ssm';
import {
BootstraplessSynthesizer, CfnResource, ConstructNode,
CfnResource, ConstructNode,
CustomResource, CustomResourceProvider, CustomResourceProviderRuntime,
DefaultStackSynthesizer, IStackSynthesizer, Resource, Stack, Stage, Token,
Resource, Stack, Stage, Token,
} from '@aws-cdk/core';
import { Construct } from 'constructs';

Expand Down Expand Up @@ -214,7 +214,6 @@ export class EdgeFunction extends Resource implements lambda.IVersion {
let edgeStack = stage.node.tryFindChild(edgeStackId) as Stack;
if (!edgeStack) {
edgeStack = new Stack(stage, edgeStackId, {
synthesizer: crossRegionSupportSynthesizer(this.stack),
env: { region: EdgeFunction.EDGE_REGION },
});
}
Expand All @@ -230,21 +229,6 @@ interface FunctionConfig {
readonly functionStack: Stack;
}

// Stolen (and modified) from `@aws-cdk/aws-codepipeline`'s `Pipeline`.
function crossRegionSupportSynthesizer(stack: Stack): IStackSynthesizer | undefined {
// If we have the new synthesizer we need a bootstrapless copy of it,
// because we don't want to require bootstrapping the environment
// of the account in this replication region.
// Otherwise, return undefined to use the default.
const scopeStackSynthesizer = stack.synthesizer;
return (scopeStackSynthesizer instanceof DefaultStackSynthesizer)
? new BootstraplessSynthesizer({
deployRoleArn: scopeStackSynthesizer.deployRoleArn,
cloudFormationExecutionRoleArn: scopeStackSynthesizer.cloudFormationExecutionRoleArn,
})
: undefined;
}

function addEdgeLambdaToRoleTrustStatement(role: iam.IRole) {
if (role instanceof iam.Role && role.assumeRolePolicy) {
const statement = new iam.PolicyStatement();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as path from 'path';
import '@aws-cdk/assert/jest';
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import * as iam from '@aws-cdk/aws-iam';
Expand Down Expand Up @@ -227,6 +228,23 @@ test('metric methods', () => {
}
});

test('cross-region stack supports new-style synthesis with assets', () => {
app = new cdk.App({
context: { '@aws-cdk/core:newStyleStackSynthesis': true },
});
stack = new cdk.Stack(app, 'Stack', {
env: { account: '111111111111', region: 'testregion' },
});

new cloudfront.experimental.EdgeFunction(stack, 'MyFn', {
code: lambda.Code.fromAsset(path.join(__dirname, 'my-lambda-handler')),
handler: 'index.handler',
runtime: lambda.Runtime.PYTHON_3_8,
});

expect(() => app.synth()).not.toThrow();
});

function defaultEdgeFunctionProps(stackId?: string) {
return {
code: lambda.Code.fromInline('foo'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
def main(event, context):
return {
'message': 'Hello, world!'
}

0 comments on commit b63172f

Please sign in to comment.