Skip to content

Commit b088c8c

Browse files
KnisterPeterrix0rrr
authored andcommitted
feat(cloudfront): add Lambda associations (#2760)
This enables to associate a lambda to a distribution behaviour. The lambda could be associated with the four available event-types.
1 parent 9ea6148 commit b088c8c

File tree

5 files changed

+235
-1
lines changed

5 files changed

+235
-1
lines changed

packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import lambda = require('@aws-cdk/aws-lambda');
12
import s3 = require('@aws-cdk/aws-s3');
23
import cdk = require('@aws-cdk/cdk');
34
import { CfnDistribution } from './cloudfront.generated';
@@ -344,6 +345,48 @@ export interface Behavior {
344345
*/
345346
readonly maxTtlSeconds?: number;
346347

348+
/**
349+
* Declares associated lambda@edge functions for this distribution behaviour.
350+
*
351+
* @default No lambda function associated
352+
*/
353+
readonly lambdaFunctionAssociations?: LambdaFunctionAssociation[];
354+
355+
}
356+
357+
export interface LambdaFunctionAssociation {
358+
359+
/**
360+
* The lambda event type defines at which event the lambda
361+
* is called during the request lifecycle
362+
*/
363+
readonly eventType: LambdaEdgeEventType;
364+
365+
/**
366+
* A version of the lambda to associate
367+
*/
368+
readonly lambdaFunction: lambda.IVersion;
369+
}
370+
371+
export enum LambdaEdgeEventType {
372+
/**
373+
* The origin-request specifies the request to the
374+
* origin location (e.g. S3)
375+
*/
376+
OriginRequest = "origin-request",
377+
/**
378+
* The origin-response specifies the response from the
379+
* origin location (e.g. S3)
380+
*/
381+
OriginResponse = "origin-response",
382+
/**
383+
* The viewer-request specifies the incoming request
384+
*/
385+
ViewerRequest = "viewer-request",
386+
/**
387+
* The viewer-response specifies the outgoing reponse
388+
*/
389+
ViewerResponse = "viewer-response",
347390
}
348391

349392
export interface ErrorConfiguration {
@@ -691,6 +734,15 @@ export class CloudFrontWebDistribution extends cdk.Construct implements IDistrib
691734
if (!input.isDefaultBehavior) {
692735
toReturn = Object.assign(toReturn, { pathPattern: input.pathPattern });
693736
}
737+
if (input.lambdaFunctionAssociations) {
738+
toReturn = Object.assign(toReturn, {
739+
lambdaFunctionAssociations: input.lambdaFunctionAssociations
740+
.map(fna => ({
741+
eventType: fna.eventType,
742+
lambdaFunctionArn: fna.lambdaFunction && fna.lambdaFunction.versionArn,
743+
}))
744+
});
745+
}
694746
return toReturn;
695747
}
696748
}

packages/@aws-cdk/aws-cloudfront/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
"@aws-cdk/aws-certificatemanager": "^0.34.0",
7575
"@aws-cdk/aws-iam": "^0.34.0",
7676
"@aws-cdk/aws-kms": "^0.34.0",
77+
"@aws-cdk/aws-lambda": "^0.34.0",
7778
"@aws-cdk/aws-s3": "^0.34.0",
7879
"@aws-cdk/cdk": "^0.34.0"
7980
},
@@ -82,11 +83,12 @@
8283
"@aws-cdk/aws-certificatemanager": "^0.34.0",
8384
"@aws-cdk/aws-iam": "^0.34.0",
8485
"@aws-cdk/aws-kms": "^0.34.0",
86+
"@aws-cdk/aws-lambda": "^0.34.0",
8587
"@aws-cdk/aws-s3": "^0.34.0",
8688
"@aws-cdk/cdk": "^0.34.0"
8789
},
8890
"engines": {
8991
"node": ">= 8.10.0"
9092
},
9193
"stability": "experimental"
92-
}
94+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
{
2+
"Resources": {
3+
"Bucket83908E77": {
4+
"Type": "AWS::S3::Bucket"
5+
},
6+
"LambdaServiceRoleA8ED4D3B": {
7+
"Type": "AWS::IAM::Role",
8+
"Properties": {
9+
"AssumeRolePolicyDocument": {
10+
"Statement": [
11+
{
12+
"Action": "sts:AssumeRole",
13+
"Effect": "Allow",
14+
"Principal": {
15+
"Service": {
16+
"Fn::Join": [
17+
"",
18+
[
19+
"lambda.",
20+
{
21+
"Ref": "AWS::URLSuffix"
22+
}
23+
]
24+
]
25+
}
26+
}
27+
}
28+
],
29+
"Version": "2012-10-17"
30+
},
31+
"ManagedPolicyArns": [
32+
{
33+
"Fn::Join": [
34+
"",
35+
[
36+
"arn:",
37+
{
38+
"Ref": "AWS::Partition"
39+
},
40+
":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
41+
]
42+
]
43+
}
44+
]
45+
}
46+
},
47+
"LambdaD247545B": {
48+
"Type": "AWS::Lambda::Function",
49+
"Properties": {
50+
"Code": {
51+
"ZipFile": "foo"
52+
},
53+
"Handler": "index.handler",
54+
"Role": {
55+
"Fn::GetAtt": [
56+
"LambdaServiceRoleA8ED4D3B",
57+
"Arn"
58+
]
59+
},
60+
"Runtime": "nodejs8.10"
61+
},
62+
"DependsOn": [
63+
"LambdaServiceRoleA8ED4D3B"
64+
]
65+
},
66+
"LambdaVersionFA49E61E": {
67+
"Type": "AWS::Lambda::Version",
68+
"Properties": {
69+
"FunctionName": {
70+
"Ref": "LambdaD247545B"
71+
}
72+
}
73+
},
74+
"MyDistributionCFDistributionDE147309": {
75+
"Type": "AWS::CloudFront::Distribution",
76+
"Properties": {
77+
"DistributionConfig": {
78+
"CacheBehaviors": [],
79+
"DefaultCacheBehavior": {
80+
"AllowedMethods": [
81+
"GET",
82+
"HEAD"
83+
],
84+
"CachedMethods": [
85+
"GET",
86+
"HEAD"
87+
],
88+
"ForwardedValues": {
89+
"Cookies": {
90+
"Forward": "none"
91+
},
92+
"QueryString": false
93+
},
94+
"TargetOriginId": "origin1",
95+
"ViewerProtocolPolicy": "redirect-to-https",
96+
"LambdaFunctionAssociations": [
97+
{
98+
"EventType": "origin-request",
99+
"LambdaFunctionARN": {
100+
"Ref": "LambdaVersionFA49E61E"
101+
}
102+
}
103+
]
104+
},
105+
"DefaultRootObject": "index.html",
106+
"Enabled": true,
107+
"HttpVersion": "http2",
108+
"IPV6Enabled": true,
109+
"Origins": [
110+
{
111+
"DomainName": {
112+
"Fn::GetAtt": [
113+
"Bucket83908E77",
114+
"RegionalDomainName"
115+
]
116+
},
117+
"Id": "origin1",
118+
"S3OriginConfig": {}
119+
}
120+
],
121+
"PriceClass": "PriceClass_100",
122+
"ViewerCertificate": {
123+
"CloudFrontDefaultCertificate": true
124+
}
125+
}
126+
}
127+
}
128+
}
129+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import lambda = require('@aws-cdk/aws-lambda');
2+
import s3 = require('@aws-cdk/aws-s3');
3+
import cdk = require('@aws-cdk/cdk');
4+
import cloudfront = require('../lib');
5+
6+
const app = new cdk.App();
7+
8+
const stack = new cdk.Stack(app, 'aws-cdk-cloudfront');
9+
10+
const sourceBucket = new s3.Bucket(stack, 'Bucket', {
11+
removalPolicy: cdk.RemovalPolicy.Destroy
12+
});
13+
14+
const lambdaFunction = new lambda.Function(stack, 'Lambda', {
15+
code: lambda.Code.inline('foo'),
16+
handler: 'index.handler',
17+
runtime: lambda.Runtime.NodeJS810
18+
});
19+
20+
const lambdaVersion = new lambda.Version(stack, 'LambdaVersion', {
21+
lambda: lambdaFunction
22+
});
23+
24+
new cloudfront.CloudFrontWebDistribution(stack, 'MyDistribution', {
25+
originConfigs: [
26+
{
27+
s3OriginSource: {
28+
s3BucketSource: sourceBucket
29+
},
30+
behaviors : [ {isDefaultBehavior: true, lambdaFunctionAssociations: [{
31+
eventType: cloudfront.LambdaEdgeEventType.OriginRequest,
32+
lambdaFunction: lambdaVersion
33+
}]}]
34+
}
35+
]
36+
});
37+
38+
app.run();

packages/@aws-cdk/aws-lambda/lib/lambda-version.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ export interface IVersion extends IResource {
99
*/
1010
readonly version: string;
1111

12+
/**
13+
* The ARN of this version.
14+
* @attribute
15+
*/
16+
readonly versionArn?: string;
17+
1218
/**
1319
* The underlying AWS Lambda function.
1420
*/
@@ -47,6 +53,11 @@ export interface VersionAttributes {
4753
*/
4854
readonly version: string;
4955

56+
/**
57+
* The version arn.
58+
*/
59+
readonly versionArn?: string;
60+
5061
/**
5162
* The lambda function.
5263
*/
@@ -80,6 +91,7 @@ export class Version extends Resource implements IVersion {
8091
}
8192

8293
public readonly version: string;
94+
public readonly versionArn?: string;
8395
public readonly lambda: IFunction;
8496

8597
constructor(scope: Construct, id: string, props: VersionProps) {
@@ -92,6 +104,7 @@ export class Version extends Resource implements IVersion {
92104
});
93105

94106
this.version = version.version;
107+
this.versionArn = version.versionArn;
95108
this.lambda = props.lambda;
96109
}
97110
}

0 commit comments

Comments
 (0)