add cloudfront trigger and custom origin type

This commit is contained in:
Eetu Tuomala 2018-01-15 23:27:48 +02:00 committed by Philipp Muens
parent b96ecc72bb
commit 524aac1768
3 changed files with 135 additions and 0 deletions

View File

@ -48,6 +48,7 @@
"./aws/package/compile/events/cognitoUserPool/index.js",
"./aws/package/compile/events/eventBridge/index.js",
"./aws/package/compile/events/sqs/index.js",
"./aws/package/compile/events/cloudFront/index.js",
"./aws/deployFunction/index.js",
"./aws/deployList/index.js",
"./aws/invokeLocal/index.js"

View File

@ -0,0 +1,134 @@
'use strict';
const _ = require('lodash');
class AwsCompileCloudFrontEvents {
constructor(serverless) {
this.serverless = serverless;
this.provider = this.serverless.getProvider('aws');
this.region =
this.serverless.processedInput.options.region || this.serverless.service.provider.region;
this.hooks = {
'package:compileEvents': this.compileCloudFrontEvents.bind(this),
};
}
compileCloudFrontEvents() {
const lambdaAtEdgeFunctions = [];
const { Resources, Outputs } = this.serverless.service.provider.compiledCloudFormationTemplate;
this.serverless.service.getAllFunctions().forEach((functionName) => {
const functionObj = this.serverless.service.getFunction(functionName);
if (functionObj.events) {
functionObj.events.forEach(event => {
if (event.cloudFront) {
// console.log(event.cloudFront);
const lambdaVersionLogicalId = _.findKey(Resources, {
Type: 'AWS::Lambda::Version',
Properties: {
FunctionName: {
Ref: this.provider.naming.getLambdaLogicalId(functionName),
},
},
});
const pathPattern =
typeof event.cloudFront.pathPattern === 'string'
? event.cloudFront.pathPattern
: undefined;
const behavior = {
ViewerProtocolPolicy: 'allow-all',
TargetOriginId: this.provider.naming.getNormalizedFunctionName(functionName),
ForwardedValues: {
QueryString: false,
},
LambdaFunctionAssociations: [{
EventType: event.cloudFront.eventType,
LambdaFunctionARN: {
Ref: lambdaVersionLogicalId,
},
}],
};
if (typeof pathPattern !== undefined) {
_.merge(behavior, { PathPattern: pathPattern });
}
const domainName =
typeof event.cloudFront.origin === 'string'
? event.cloudFront.origin
: event.cloudFront.origin.domainName;
const origin = {
Id: this.provider.naming.getNormalizedFunctionName(functionName),
DomainName: domainName,
CustomOriginConfig: {
OriginProtocolPolicy: 'match-viewer',
},
};
lambdaAtEdgeFunctions.push(_.merge({
cloudFront: { origin, behavior } },
functionObj));
}
});
}
});
if (lambdaAtEdgeFunctions.length > 0) {
if (this.region !== 'us-east-1') {
throw new Error('CloudFront triggered functions has to be deployed to us-east-1 region.');
}
Resources
.IamRoleLambdaExecution
.Properties
.AssumeRolePolicyDocument
.Statement.push({
Effect: 'Allow',
Principal: {
Service: ['edgelambda.amazonaws.com'],
},
Action: ['sts:AssumeRole'],
});
const CacheBehaviors =
lambdaAtEdgeFunctions
.filter(({ cloudFront }) => !!cloudFront.behavior.PathPattern)
.map(({ cloudFront }) => cloudFront.behavior);
const CloudFrontDistribution = {
Type: 'AWS::CloudFront::Distribution',
Properties: {
DistributionConfig: {
Enabled: true,
DefaultCacheBehavior:
lambdaAtEdgeFunctions
.filter(({ cloudFront }) => !cloudFront.behavior.PathPattern)
.map(({ cloudFront }) => cloudFront.behavior)[0],
Origins: lambdaAtEdgeFunctions.map(({ cloudFront }) => cloudFront.origin),
},
},
};
if (typeof CacheBehaviors !== 'undefined') {
_.merge(CloudFrontDistribution.Properties.DistributionConfig, { CacheBehaviors });
}
_.merge(Resources, { CloudFrontDistribution });
_.merge(Outputs, {
CloudFrontDistributionDomainName: {
Description: 'CloudFront distribution domain name',
Value: {
'Fn::GetAtt': ['CloudFrontDistribution', 'DomainName'],
},
},
});
}
}
}
module.exports = AwsCompileCloudFrontEvents;