AWS CloudFront URL rewriting

Philipp Steinwender
2 min readApr 9, 2021

At our company, we want to host different applications in the same domain. With AWS CloudFront it is easy to create a distribution and configure behaviors to serve these applications under a specific path.

So we get a structure, like this:

https://company.com/ → Landing Page
https://company.com/app/ → Webapp
https://company.com/api/ → Backend API

This way, we don’t need to care about preflight requests, or cookies not being shared across subdomains.

Sadly, rewriting the URL of the request to the origin is not simple at all.

Our origin applications are served on the root context (/) internally. A resource of the Backend API for example is available at api.company.com/resource. But with the CloudFront behavior described above, every request to the origin is getting prefixed with /api . CloudFront tries to fetch the resource at api.company.com/api/resource , which does not exist.

Client:
GET https://company.com/api/resource
CloudFront:
GET https://api.company.com/api/resource
Actual URL:
GET https://api.company.com/resource

What we want is to remove the prefix /api of the request made by CloudFront to the origin. This option is not available. The easiest way I found to rewrite the URL is by using a Lambda function.

AWS Lambda@Edge

To alter the request path of the origin resource, a Lambda function can be used.

Once defined, it can be associated with the CloudFront behavior. Pick the event type Origin Request , so the function gets executed before the request is sent to the origin.

exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
if (request.uri.indexOf("/", 1) < 0) {
request.uri = "/"
} else {
request.uri = request.uri.replace(/^\/[^\/]+\//,'/');
}
return callback(null, request);
};

The path prefix is removed from the origin request, like shown in the examples below:

""                -> "/"
"/" -> "/"
"/api" -> "/"
"/api/" -> "/"
"/api/resource" -> "/resource"
"/api/resource/1" -> "/resource/1"

See also:

--

--