Skip to content

Commit

Permalink
fix(cloudfront): Distribution does not add edgelambda trust policy (#…
Browse files Browse the repository at this point in the history
…10006)

The stable `CloudFrontWebDistribution` construct automatically adds the
'edgelambda.amazonaws.com' trust policy to the Lambda execution role when
adding a Lambda@Edge function to the distribution. The newer `Distribution`
construct was missing this functionality.

Also added an integ test to validate the Lambda@Edge functions can actually be
deployed.

fixes #9998

----

*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 committed Aug 28, 2020
1 parent ff33b54 commit 9098e29
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 1 deletion.
18 changes: 17 additions & 1 deletion packages/@aws-cdk/aws-cloudfront/lib/private/cache-behavior.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as iam from '@aws-cdk/aws-iam';
import { CfnDistribution } from '../cloudfront.generated';
import { AddBehaviorOptions, ViewerProtocolPolicy } from '../distribution';
import { AddBehaviorOptions, EdgeLambda, ViewerProtocolPolicy } from '../distribution';

/**
* Properties for specifying custom behaviors for origins.
Expand All @@ -24,6 +25,8 @@ export class CacheBehavior {

constructor(originId: string, private readonly props: CacheBehaviorProps) {
this.originId = originId;

this.grantEdgeLambdaFunctionExecutionRole(props.edgeLambdas);
}

/**
Expand Down Expand Up @@ -55,4 +58,17 @@ export class CacheBehavior {
: undefined,
};
}

private grantEdgeLambdaFunctionExecutionRole(edgeLambdas?: EdgeLambda[]) {
if (!edgeLambdas || edgeLambdas.length === 0) { return; }
edgeLambdas.forEach((edgeLambda) => {
const role = edgeLambda.functionVersion.role;
if (role && role instanceof iam.Role && role.assumeRolePolicy) {
role.assumeRolePolicy.addStatements(new iam.PolicyStatement({
actions: ['sts:AssumeRole'],
principals: [new iam.ServicePrincipal('edgelambda.amazonaws.com')],
}));
}
});
}
}
36 changes: 36 additions & 0 deletions packages/@aws-cdk/aws-cloudfront/test/distribution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,42 @@ describe('with Lambda@Edge functions', () => {
});
});

test('edgelambda.amazonaws.com is added to the trust policy of lambda', () => {
new Distribution(stack, 'MyDist', {
defaultBehavior: {
origin,
edgeLambdas: [
{
functionVersion: lambdaFunction.currentVersion,
eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
},
],
},
});

expect(stack).toHaveResource('AWS::IAM::Role', {
AssumeRolePolicyDocument: {
Statement: [
{
Action: 'sts:AssumeRole',
Effect: 'Allow',
Principal: {
Service: 'lambda.amazonaws.com',
},
},
{
Action: 'sts:AssumeRole',
Effect: 'Allow',
Principal: {
Service: 'edgelambda.amazonaws.com',
},
},
],
Version: '2012-10-17',
},
});
});

test('can add an edge lambdas to additional behaviors', () => {
new Distribution(stack, 'MyDist', {
defaultBehavior: { origin },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{
"Resources": {
"LambdaServiceRoleA8ED4D3B": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
}
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "edgelambda.amazonaws.com"
}
}
],
"Version": "2012-10-17"
},
"ManagedPolicyArns": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
]
]
}
]
}
},
"LambdaD247545B": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"ZipFile": "foo"
},
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"LambdaServiceRoleA8ED4D3B",
"Arn"
]
},
"Runtime": "nodejs10.x"
},
"DependsOn": [
"LambdaServiceRoleA8ED4D3B"
]
},
"LambdaCurrentVersionDF706F6A97fb843e9bd06fcd2bb15eeace80e13e": {
"Type": "AWS::Lambda::Version",
"Properties": {
"FunctionName": {
"Ref": "LambdaD247545B"
}
}
},
"DistB3B78991": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"DefaultCacheBehavior": {
"ForwardedValues": {
"QueryString": false
},
"LambdaFunctionAssociations": [
{
"EventType": "origin-request",
"LambdaFunctionARN": {
"Ref": "LambdaCurrentVersionDF706F6A97fb843e9bd06fcd2bb15eeace80e13e"
}
}
],
"TargetOriginId": "integdistributionlambdaDistOrigin133A13098",
"ViewerProtocolPolicy": "allow-all"
},
"Enabled": true,
"HttpVersion": "http2",
"IPV6Enabled": true,
"Origins": [
{
"CustomOriginConfig": {
"OriginProtocolPolicy": "https-only"
},
"DomainName": "www.example.com",
"Id": "integdistributionlambdaDistOrigin133A13098"
}
]
}
}
}
}
}
25 changes: 25 additions & 0 deletions packages/@aws-cdk/aws-cloudfront/test/integ.distribution-lambda.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as lambda from '@aws-cdk/aws-lambda';
import * as cdk from '@aws-cdk/core';
import * as cloudfront from '../lib';
import { TestOrigin } from './test-origin';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'integ-distribution-lambda', { env: { region: 'us-east-1' } });

const lambdaFunction = new lambda.Function(stack, 'Lambda', {
code: lambda.Code.fromInline('foo'),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_10_X,
});

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

app.synth();

0 comments on commit 9098e29

Please sign in to comment.