Running lambdas as your server with cloudfront.

January 11, 2017

So recently in my work I have wanted to pre-render some of our pages and then keep the cached version in cloudwatch.

There are a few options in doing this.

You can set up an EC2 instance. Or use ECS.

However, what if you don't want to pay to have and EC2 instance running all the time. You have a budget!

Enter lambdas. AWS lambdas can be created to run based on events. Sadly you can't directly integrate with lambda from cloudwatch (except for lambda@edge but that is a different use case). This isn't too hard AWS even has a nice article on it for us. http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started.html

But API gateway is normally setup for sending JSON. For our use case we just want to pre-render our HTML when cloudfront doesn't have it in cache.

A few changes will have to be made. First off in API gateway we want to proxy all requests to lambda. create the lambda

Now in our lambda when we return our data we need to tell API gateway it is text/html

exports.handler = (event, context, callback) =>{
  //Do our pre-rendering
  callback(null, {
    statusCode: 200,
    body: preRenderedBody,
      "Content-Type": "text/html"

Back to API gateway again. We need to set our response header as text/html as well. The model doesn't much matter.

set stuff

Not super hard so far but it did take some figuring out so I thought I would put it all in one place.

But we have one more thing we want to do. Put cloudfront in front of it.

So you'll want to go to cloudfront and create a distribution.

create distribution

In Origin Domain Name you will want to put the domain name of the API gateway you created.

Origin Path should be the stage you created for your API gateway. eg /prod

The rest of the settings can be set to your liking. One word of caution. Do not forward the host header to API gateway it will break things.

We don't want API gateway to handle all files just the main page. If we are storing all our files in s3 we can create another origin for those.

So after creating our distribution, go into it and Click on the tab Origins so we can add our s3 as one. The process is the same as the first origin we created above. Except if you just click in the box it will give you a dropdown of s3 buckets you can choose.

Now after we have our two origins we have to setup a new behaviour to handle it.

Our API gateway is going to handle / and we want s3 to serve anything else.


Using /?* tells cloudfront to use any path with one or more characters to path to our s3 bucket.

These should be all the steps. Questions and comments can be directed to @powerc9000 on twitter.