Caching in with CloudFront using Serverless

Joseph Schofield
Aug 23, 2018 · 8 min read
“A low-angle shot of a canopy of bamboo leaves” by kazuend on Unsplash

$ sls deploy -s dev

What you will create in this tutorial:

  • A deployed Lambda — Where your code will run. This will sit behind an API Gateway, but you don’t need to worry about that.
  • A CloudFront Distribution with a cache — this makes sure your service is available worldwide, with very little latency. It also manages the cache.

Got all that? Awesome let’s go!


Taking our first steps

We need to create a serverless project.

$ sls create --template aws-nodejs --path my-service$ cd my-service

Step the second

Now’s a good time to edit your handler if you want to. This is where all the Lambda logic happens. The handler is found in handler.js (funnily enough). And by default will just return some JSON. Feel free to change this code to do whatever you like. For this tutorial I’m just leaving it as it is.

service: my-serviceprovider:
  name: aws
  runtime: nodejs6.10functions:
  hello:
    handler: handler.hello

St3p

That functions section is looking awfully bare. Let’s add the following properties, alongside the handler property:

  • events : This will contain the events that will trigger the lambda
- http:
    path: my/cool/path
    method: get

service: my-serviceprovider:
  name: aws
  runtime: nodejs8.11functions:
  hello:
    handler: handler.hello
    description: my plain old handler, does nothing
    events:
      - http:
          path: my/cool/path
          method: get

Step Quatro

So let’s try deploying. Just one more time for those that haven’t been paying attention…

$ sls deploy -s dev
“Cappuccino in a white cup on a saucer with foam art and a small spoon” by Jason Wong on Unsplash
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (409 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
....................................
Serverless: Stack update finished...
Service Information
service: my-service
stage: dev
region: us-east-1
stack: my-service-dev
api keys:
  None
endpoints:
  GET - https://<some_ID>.execute-api.us-east-1.amazonaws.com/dev/my/cool/path
functions:
  hello: my-service-dev-hello
Serverless: Publish service to Serverless Platform...
Service successfully published! Your service details are available at:
https://platform.serverless.com/services/<Your_User>/my-service
message: "Go Serverless v1.0! Your function executed successfully!

x-cache: Miss from cloudfront

5tep

To enable caching is a little more complex than what we’ve been doing. But not so complex that you’ll leave this tutorial.

resources:
  Resources:
    CloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          Comment: My first CloudFront Distribution
          DefaultCacheBehavior:
            TargetOriginId: MyFirstOrigin
            ViewerProtocolPolicy: 'redirect-to-https'
            DefaultTTL: 30
            ForwardedValues:
              QueryString: false
          Enabled: true
          Origins:
            - Id: MyFirstOrigin
            DomainName: <some_ID>.execute-api.us-east-1.amazonaws.com
            OriginPath: /dev/my/cool/path
            CustomOriginConfig:
            OriginProtocolPolicy: https-only
Photo by Franck V. on Unsplash

Section 1 — Type

resources:
  Resources:
    CloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
  • Type: AWS::CloudFront::Distribution tells AWS what it needs to create. There are many different types of these, but they are pretty well documented by AWS.

Section 2 — Properties

resources:
  Resources:
    CloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          Comment: My first CloudFront Distribution
          DefaultCacheBehavior:
            TargetOriginId: MyFirstOrigin
            ViewerProtocolPolicy: 'redirect-to-https'
            DefaultTTL: 30
            ForwardedValues:
              QueryString: false
          Enabled: true
          Origins:
            - Id: MyFirstOrigin
              DomainName:
                Fn::Join:
                  - "."
                  - - Ref: ApiGatewayRestApi
                  - execute-api
                  - us-east-1
                  - amazonaws.com
              OriginPath: /dev
              CustomOriginConfig:
                HTTPPort: 80
                HTTPSPort: 443
                OriginProtocolPolicy: https-only
  • DefaultCacheBehaviour — How you would like the cache to behave
  • Enabled — Will the distribution accept and respond to HTTP requests?
  • Origins — The location of the URL from which to cache data

service: my-serviceprovider:
  name: aws
  runtime: nodejs6.10functions:
  hello:
    handler: handler.hello
    description: my plain old handler, does nothing
    events:
      - http:
          path: my/cool/path
          method: getresources:
  Resources:
    CloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          Comment: My first CloudFront Distribution
          DefaultCacheBehavior:
            TargetOriginId: MyFirstOrigin
            ViewerProtocolPolicy: 'redirect-to-https'
            DefaultTTL: 30
            ForwardedValues:
              QueryString: false
          Enabled: true
          Origins:
            - Id: MyFirstOrigin
              DomainName:
                Fn::Join:
                  - "."
                  - - Ref: ApiGatewayRestApi
                    - execute-api.us-east-1.amazonaws.com
              OriginPath: /dev
              CustomOriginConfig:
                HTTPPort: 80
                HTTPSPort: 443
                OriginProtocolPolicy: https-only
$ sls deploy -s dev

$ curl -v <your cloudfront domain>/my/cool/path | jq
x-cache: Miss from cloudfront
x-cache: Hit from cloudfront

An end to the madness

So let’s think about what we’ve created.

$ sls remove -s dev

YLD Blog

YLD's latest thoughts on Software Engineering, Design and Digital Products

Joseph Schofield

Written by

YLD Blog

YLD Blog

YLD's latest thoughts on Software Engineering, Design and Digital Products