diff --git a/README.md b/README.md index 31c358a..cbddc42 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,10 @@ distribution: inputs: region: us-east-1 enabled: true # optional + defaults: # optional + ttl: 15 + lambda@edge: # added to cloudfront default cache behavior + viewer-request: arn:aws:lambda:us-east-1:123:function:myFunc:version origins: - https://my-bucket.s3.amazonaws.com ``` diff --git a/__tests__/__snapshots__/custom-url-origin.test.js.snap b/__tests__/__snapshots__/custom-url-origin.test.js.snap index 4aebf38..21b3a5d 100644 --- a/__tests__/__snapshots__/custom-url-origin.test.js.snap +++ b/__tests__/__snapshots__/custom-url-origin.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Input origin as a custom url creates distribution with custom url origin 1`] = ` +exports[`Input origin as a custom url creates distribution with custom url origin and sets defaults 1`] = ` Object { "DistributionConfig": Object { "Aliases": Object { @@ -29,7 +29,7 @@ Object { "Quantity": 2, }, "Compress": false, - "DefaultTTL": 86400, + "DefaultTTL": 10, "FieldLevelEncryptionId": "", "ForwardedValues": Object { "Cookies": Object { @@ -46,8 +46,14 @@ Object { }, }, "LambdaFunctionAssociations": Object { - "Items": Array [], - "Quantity": 0, + "Items": Array [ + Object { + "EventType": "origin-request", + "IncludeBody": true, + "LambdaFunctionARN": "arn:aws:lambda:us-east-1:123:function:originRequestFunction", + }, + ], + "Quantity": 1, }, "MaxTTL": 31536000, "MinTTL": 0, diff --git a/__tests__/custom-url-origin.test.js b/__tests__/custom-url-origin.test.js index f3077f1..a730ef1 100644 --- a/__tests__/custom-url-origin.test.js +++ b/__tests__/custom-url-origin.test.js @@ -21,8 +21,14 @@ describe('Input origin as a custom url', () => { component = await createComponent() }) - it('creates distribution with custom url origin', async () => { + it('creates distribution with custom url origin and sets defaults', async () => { await component.default({ + defaults: { + ttl: 10, + 'lambda@edge': { + 'origin-request': 'arn:aws:lambda:us-east-1:123:function:originRequestFunction' + } + }, origins: ['https://mycustomorigin.com'] }) diff --git a/lib/addLambdaAtEdgeToCacheBehavior.js b/lib/addLambdaAtEdgeToCacheBehavior.js new file mode 100644 index 0000000..6728691 --- /dev/null +++ b/lib/addLambdaAtEdgeToCacheBehavior.js @@ -0,0 +1,25 @@ +const validLambdaTriggers = [ + 'viewer-request', + 'origin-request', + 'origin-response', + 'viewer-response' +] + +// adds lambda@edge to cache behavior passed +module.exports = (cacheBehavior, lambdaAtEdgeConfig = {}) => { + Object.keys(lambdaAtEdgeConfig).forEach((eventType) => { + if (!validLambdaTriggers.includes(eventType)) { + throw new Error( + `"${eventType}" is not a valid lambda trigger. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html for valid event types.` + ) + } + + cacheBehavior.LambdaFunctionAssociations.Quantity = + cacheBehavior.LambdaFunctionAssociations.Quantity + 1 + cacheBehavior.LambdaFunctionAssociations.Items.push({ + EventType: eventType, + LambdaFunctionARN: lambdaAtEdgeConfig[eventType], + IncludeBody: true + }) + }) +} diff --git a/lib/getDefaultCacheBehavior.js b/lib/getDefaultCacheBehavior.js index 3e7bafa..0f1b5a9 100644 --- a/lib/getDefaultCacheBehavior.js +++ b/lib/getDefaultCacheBehavior.js @@ -1,5 +1,7 @@ -module.exports = (originId) => { - return { +const addLambdaAtEdgeToCacheBehavior = require('./addLambdaAtEdgeToCacheBehavior') + +module.exports = (originId, defaults = {}) => { + const defaultCacheBehavior = { TargetOriginId: originId, ForwardedValues: { QueryString: false, @@ -31,7 +33,7 @@ module.exports = (originId) => { } }, SmoothStreaming: false, - DefaultTTL: 86400, + DefaultTTL: defaults.ttl || 86400, MaxTTL: 31536000, Compress: false, LambdaFunctionAssociations: { @@ -40,4 +42,8 @@ module.exports = (originId) => { }, FieldLevelEncryptionId: '' } + + addLambdaAtEdgeToCacheBehavior(defaultCacheBehavior, defaults['lambda@edge']) + + return defaultCacheBehavior } diff --git a/lib/index.js b/lib/index.js index bd64ccd..fc4a0a0 100644 --- a/lib/index.js +++ b/lib/index.js @@ -56,7 +56,10 @@ const createCloudFrontDistribution = async (cf, s3, inputs) => { distributionConfig.Origins = Origins // set first origin declared as the default cache behavior - distributionConfig.DefaultCacheBehavior = getDefaultCacheBehavior(Origins.Items[0].Id) + distributionConfig.DefaultCacheBehavior = getDefaultCacheBehavior( + Origins.Items[0].Id, + inputs.defaults + ) if (CacheBehaviors) { distributionConfig.CacheBehaviors = CacheBehaviors @@ -108,7 +111,10 @@ const updateCloudFrontDistribution = async (cf, s3, distributionId, inputs) => { await updateBucketsPolicies(s3, Origins, s3CanonicalUserId) } - params.DistributionConfig.DefaultCacheBehavior = getDefaultCacheBehavior(Origins.Items[0].Id) + params.DistributionConfig.DefaultCacheBehavior = getDefaultCacheBehavior( + Origins.Items[0].Id, + inputs.defaults + ) params.DistributionConfig.Origins = Origins if (CacheBehaviors) { diff --git a/lib/parseInputOrigins.js b/lib/parseInputOrigins.js index 4052b66..ac634c0 100644 --- a/lib/parseInputOrigins.js +++ b/lib/parseInputOrigins.js @@ -1,12 +1,7 @@ const getOriginConfig = require('./getOriginConfig') const getCacheBehavior = require('./getCacheBehavior') +const addLambdaAtEdgeToCacheBehavior = require('./addLambdaAtEdgeToCacheBehavior') -const validLambdaTriggers = [ - 'viewer-request', - 'origin-request', - 'origin-response', - 'viewer-response' -] module.exports = (origins, options) => { const distributionOrigins = { Quantity: 0, @@ -30,23 +25,7 @@ module.exports = (origins, options) => { const pathPatternConfig = origin.pathPatterns[pathPattern] const cacheBehavior = getCacheBehavior(pathPattern, pathPatternConfig, originConfig.Id) - const lambdaAtEdge = pathPatternConfig['lambda@edge'] || {} - - Object.keys(lambdaAtEdge).forEach((eventType) => { - if (!validLambdaTriggers.includes(eventType)) { - throw new Error( - `"${eventType}" is not a valid lambda trigger. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html for valid event types.` - ) - } - - cacheBehavior.LambdaFunctionAssociations.Quantity = - cacheBehavior.LambdaFunctionAssociations.Quantity + 1 - cacheBehavior.LambdaFunctionAssociations.Items.push({ - EventType: eventType, - LambdaFunctionARN: lambdaAtEdge[eventType], - IncludeBody: true - }) - }) + addLambdaAtEdgeToCacheBehavior(cacheBehavior, pathPatternConfig['lambda@edge']) distributionCacheBehaviors.Quantity = distributionCacheBehaviors.Quantity + 1 distributionCacheBehaviors.Items.push(cacheBehavior) diff --git a/serverless.js b/serverless.js index 1d47918..ff35320 100644 --- a/serverless.js +++ b/serverless.js @@ -36,7 +36,10 @@ class CloudFront extends Component { }) if (this.state.id) { - if (!equals(this.state.origins, inputs.origins)) { + if ( + !equals(this.state.origins, inputs.origins) || + !equals(this.state.defaults, inputs.defaults) + ) { this.context.debug(`Updating CloudFront distribution of ID ${this.state.id}.`) this.state = await updateCloudFrontDistribution(cf, s3, this.state.id, inputs) } @@ -47,6 +50,7 @@ class CloudFront extends Component { this.state.region = inputs.region this.state.origins = inputs.origins + this.state.defaults = inputs.defaults await this.save() this.context.debug(`CloudFront deployed successfully with URL: ${this.state.url}.`)