Skip to content

Commit

Permalink
fix(cloudfront): associated lambda role requires edgelambda.amazonaws…
Browse files Browse the repository at this point in the history
….com (#5191)

* fix(cloudfront): associated lambda role requires edgelambda.amazonaws.com

When using AWS Lambda associations, CloudFront now requires that the AWS Lambda execution role will also trust edgelambda.amazonaws.com. This change adds a statement to the Lambda's trust policy to that effect.

Fixes #5180

* add unit tests
  • Loading branch information
Elad Ben-Israel authored and mergify[bot] committed Nov 26, 2019
1 parent d5c0f3e commit 173d886
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 7 deletions.
11 changes: 11 additions & 0 deletions packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import certificatemanager = require('@aws-cdk/aws-certificatemanager');
import iam = require('@aws-cdk/aws-iam');
import lambda = require('@aws-cdk/aws-lambda');
import s3 = require('@aws-cdk/aws-s3');
import cdk = require('@aws-cdk/core');
Expand Down Expand Up @@ -827,6 +828,16 @@ export class CloudFrontWebDistribution extends cdk.Construct implements IDistrib
lambdaFunctionArn: fna.lambdaFunction && fna.lambdaFunction.functionArn,
}))
});

// allow edgelambda.amazonaws.com to assume the functions' execution role.
for (const a of input.lambdaFunctionAssociations) {
if (a.lambdaFunction.role && a.lambdaFunction.role instanceof iam.Role && a.lambdaFunction.role.assumeRolePolicy) {
a.lambdaFunction.role.assumeRolePolicy.addStatements(new iam.PolicyStatement({
actions: [ 'sts:AssumeRole' ],
principals: [ new iam.ServicePrincipal('edgelambda.amazonaws.com') ]
}));
}
}
}
return toReturn;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"Resources": {
"Bucket83908E77": {
"DeletionPolicy": "Delete",
"Type": "AWS::S3::Bucket",
"UpdateReplacePolicy": "Delete",
"Type": "AWS::S3::Bucket"
"DeletionPolicy": "Delete"
},
"LambdaServiceRoleA8ED4D3B": {
"Type": "AWS::IAM::Role",
Expand All @@ -16,6 +16,13 @@
"Principal": {
"Service": "lambda.amazonaws.com"
}
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "edgelambda.amazonaws.com"
}
}
],
"Version": "2012-10-17"
Expand Down Expand Up @@ -76,14 +83,13 @@
"GET",
"HEAD"
],
"Compress": true,
"ForwardedValues": {
"Cookies": {
"Forward": "none"
},
"QueryString": false
},
"TargetOriginId": "origin1",
"ViewerProtocolPolicy": "redirect-to-https",
"LambdaFunctionAssociations": [
{
"EventType": "origin-request",
Expand All @@ -92,7 +98,8 @@
}
}
],
"Compress": true
"TargetOriginId": "origin1",
"ViewerProtocolPolicy": "redirect-to-https"
},
"DefaultRootObject": "index.html",
"Enabled": true,
Expand All @@ -118,4 +125,4 @@
}
}
}
}
}
85 changes: 84 additions & 1 deletion packages/@aws-cdk/aws-cloudfront/test/test.basic.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expect, haveResourceLike } from '@aws-cdk/assert';
import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert';
import certificatemanager = require('@aws-cdk/aws-certificatemanager');
import * as lambda from '@aws-cdk/aws-lambda';
import s3 = require('@aws-cdk/aws-s3');
Expand Down Expand Up @@ -787,4 +787,87 @@ export = {
}
},

'edgelambda.amazonaws.com is added to the trust policy of lambda'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const sourceBucket = new s3.Bucket(stack, 'Bucket');
const fn = new lambda.Function(stack, 'Lambda', {
code: lambda.Code.fromInline('foo'),
handler: 'index.handler',
runtime: lambda.Runtime.NODEJS_10_X
});
const lambdaVersion = new lambda.Version(stack, 'LambdaVersion', { lambda: fn });

// WHEN
new CloudFrontWebDistribution(stack, 'MyDistribution', {
originConfigs: [
{
s3OriginSource: { s3BucketSource: sourceBucket },
behaviors : [
{
isDefaultBehavior: true, lambdaFunctionAssociations: [
{
eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
lambdaFunction: lambdaVersion
}
]
}
]
}
]
});

// THEN
expect(stack).to(haveResource('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.done();
},

'edgelambda.amazonaws.com is not added to lambda role for imported functions'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const sourceBucket = new s3.Bucket(stack, 'Bucket');
const lambdaVersion = lambda.Version.fromVersionArn(stack, 'Version', 'arn:my-version');

// WHEN
new CloudFrontWebDistribution(stack, 'MyDistribution', {
originConfigs: [
{
s3OriginSource: { s3BucketSource: sourceBucket },
behaviors : [
{
isDefaultBehavior: true, lambdaFunctionAssociations: [
{
eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
lambdaFunction: lambdaVersion
}
]
}
]
}
]
});

expect(stack).notTo(haveResourceLike('AWS::IAM::Role'));
test.done();
}
};

0 comments on commit 173d886

Please sign in to comment.