Skip to content

Commit

Permalink
feat(cloudfront): add Lambda associations (#2760)
Browse files Browse the repository at this point in the history
This enables to associate a lambda to a distribution behaviour. The lambda could be associated with the four available event-types.
  • Loading branch information
KnisterPeter authored and rix0rrr committed Jun 12, 2019
1 parent 9ea6148 commit b088c8c
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 1 deletion.
52 changes: 52 additions & 0 deletions packages/@aws-cdk/aws-cloudfront/lib/web_distribution.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import lambda = require('@aws-cdk/aws-lambda');
import s3 = require('@aws-cdk/aws-s3');
import cdk = require('@aws-cdk/cdk');
import { CfnDistribution } from './cloudfront.generated';
Expand Down Expand Up @@ -344,6 +345,48 @@ export interface Behavior {
*/
readonly maxTtlSeconds?: number;

/**
* Declares associated lambda@edge functions for this distribution behaviour.
*
* @default No lambda function associated
*/
readonly lambdaFunctionAssociations?: LambdaFunctionAssociation[];

}

export interface LambdaFunctionAssociation {

/**
* The lambda event type defines at which event the lambda
* is called during the request lifecycle
*/
readonly eventType: LambdaEdgeEventType;

/**
* A version of the lambda to associate
*/
readonly lambdaFunction: lambda.IVersion;
}

export enum LambdaEdgeEventType {
/**
* The origin-request specifies the request to the
* origin location (e.g. S3)
*/
OriginRequest = "origin-request",
/**
* The origin-response specifies the response from the
* origin location (e.g. S3)
*/
OriginResponse = "origin-response",
/**
* The viewer-request specifies the incoming request
*/
ViewerRequest = "viewer-request",
/**
* The viewer-response specifies the outgoing reponse
*/
ViewerResponse = "viewer-response",
}

export interface ErrorConfiguration {
Expand Down Expand Up @@ -691,6 +734,15 @@ export class CloudFrontWebDistribution extends cdk.Construct implements IDistrib
if (!input.isDefaultBehavior) {
toReturn = Object.assign(toReturn, { pathPattern: input.pathPattern });
}
if (input.lambdaFunctionAssociations) {
toReturn = Object.assign(toReturn, {
lambdaFunctionAssociations: input.lambdaFunctionAssociations
.map(fna => ({
eventType: fna.eventType,
lambdaFunctionArn: fna.lambdaFunction && fna.lambdaFunction.versionArn,
}))
});
}
return toReturn;
}
}
4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-cloudfront/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"@aws-cdk/aws-certificatemanager": "^0.34.0",
"@aws-cdk/aws-iam": "^0.34.0",
"@aws-cdk/aws-kms": "^0.34.0",
"@aws-cdk/aws-lambda": "^0.34.0",
"@aws-cdk/aws-s3": "^0.34.0",
"@aws-cdk/cdk": "^0.34.0"
},
Expand All @@ -82,11 +83,12 @@
"@aws-cdk/aws-certificatemanager": "^0.34.0",
"@aws-cdk/aws-iam": "^0.34.0",
"@aws-cdk/aws-kms": "^0.34.0",
"@aws-cdk/aws-lambda": "^0.34.0",
"@aws-cdk/aws-s3": "^0.34.0",
"@aws-cdk/cdk": "^0.34.0"
},
"engines": {
"node": ">= 8.10.0"
},
"stability": "experimental"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{
"Resources": {
"Bucket83908E77": {
"Type": "AWS::S3::Bucket"
},
"LambdaServiceRoleA8ED4D3B": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": {
"Fn::Join": [
"",
[
"lambda.",
{
"Ref": "AWS::URLSuffix"
}
]
]
}
}
}
],
"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": "nodejs8.10"
},
"DependsOn": [
"LambdaServiceRoleA8ED4D3B"
]
},
"LambdaVersionFA49E61E": {
"Type": "AWS::Lambda::Version",
"Properties": {
"FunctionName": {
"Ref": "LambdaD247545B"
}
}
},
"MyDistributionCFDistributionDE147309": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"CacheBehaviors": [],
"DefaultCacheBehavior": {
"AllowedMethods": [
"GET",
"HEAD"
],
"CachedMethods": [
"GET",
"HEAD"
],
"ForwardedValues": {
"Cookies": {
"Forward": "none"
},
"QueryString": false
},
"TargetOriginId": "origin1",
"ViewerProtocolPolicy": "redirect-to-https",
"LambdaFunctionAssociations": [
{
"EventType": "origin-request",
"LambdaFunctionARN": {
"Ref": "LambdaVersionFA49E61E"
}
}
]
},
"DefaultRootObject": "index.html",
"Enabled": true,
"HttpVersion": "http2",
"IPV6Enabled": true,
"Origins": [
{
"DomainName": {
"Fn::GetAtt": [
"Bucket83908E77",
"RegionalDomainName"
]
},
"Id": "origin1",
"S3OriginConfig": {}
}
],
"PriceClass": "PriceClass_100",
"ViewerCertificate": {
"CloudFrontDefaultCertificate": true
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import lambda = require('@aws-cdk/aws-lambda');
import s3 = require('@aws-cdk/aws-s3');
import cdk = require('@aws-cdk/cdk');
import cloudfront = require('../lib');

const app = new cdk.App();

const stack = new cdk.Stack(app, 'aws-cdk-cloudfront');

const sourceBucket = new s3.Bucket(stack, 'Bucket', {
removalPolicy: cdk.RemovalPolicy.Destroy
});

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

const lambdaVersion = new lambda.Version(stack, 'LambdaVersion', {
lambda: lambdaFunction
});

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

app.run();
13 changes: 13 additions & 0 deletions packages/@aws-cdk/aws-lambda/lib/lambda-version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export interface IVersion extends IResource {
*/
readonly version: string;

/**
* The ARN of this version.
* @attribute
*/
readonly versionArn?: string;

/**
* The underlying AWS Lambda function.
*/
Expand Down Expand Up @@ -47,6 +53,11 @@ export interface VersionAttributes {
*/
readonly version: string;

/**
* The version arn.
*/
readonly versionArn?: string;

/**
* The lambda function.
*/
Expand Down Expand Up @@ -80,6 +91,7 @@ export class Version extends Resource implements IVersion {
}

public readonly version: string;
public readonly versionArn?: string;
public readonly lambda: IFunction;

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

this.version = version.version;
this.versionArn = version.versionArn;
this.lambda = props.lambda;
}
}

0 comments on commit b088c8c

Please sign in to comment.