CloudFront error pages for custom origins
At Better, we try our best to give our users the greatest possible experience. In order to achieve this, we employ continuous deployment of our website resulting in multiple deploys per day. The overwhelming majority of the time this has no effect on our stability. On the rare occasions where there is an issue - rather than presenting users with scary, ugly, and opaque error pages devoid of any helpful messaging - we'd like to present them with something that reassures them of the work we're doing to resolve whatever the issue may be. There are also occasions when we wish to completely redeploy our cluster resulting in changes to the public IPs clients should be making requests to.
As our infrastructure runs on AWS we had previously solved these problems using DNS. These solutions were:
- A Route53 health check that updated the DNS record for better.com on outages to point to a static error page.
- Manual DNS changes on cluster redeploys.
As DNS caching occurs at name servers and clients this can result in clients making requests to IPs that are no longer accurate. This can persist for hours in the case of clients with aggressive caches and even when everything works as expected can take many minutes.
Our current solution is to use CloudFront as a reverse proxy with custom error responses for HTTP status codes of 502, 503, or 504 served from S3. This has the benefit of providing user-friendly error pages without the annoyances of DNS record updates and allowing us to completely update the cluster in one fell swoop. As we run all on Kuberenetes having a reverse proxy which exists outside of that cluster makes upgrading the cluster much easier. CloudFront performs this task and has been incredibly easy to manage.
How to enable customized error pages for CloudFront custom origins
Create a CloudFront distribution that forwards requests to a custom origin. Specify an alternate domain, SSL cert, and any caching behavior you would like here.
Add a secondary origin which will forward requests to an S3 bucket, in which you will place your custom error page/s.
Decide upon the path you would like to serve your custom error page/s from. This should not conflict with any path you would like to be served from the custom origin. For this demonstration, we will use /error-pages/*.
Add a behavior that forwards all requests to your S3 bucket for the path you specified in the previous step.
Add any content you would like to display to users on errors to the S3 bucket you are forwarding requests to at the subpath which matches the forwarding path. In our case this would be s3://<bucket_name>/error-pages/.
The final step is to create custom error responses. This is as simple as deciding upon the HTTP status codes you would like to intercept errors for, creating an error response, and customizing it to serve content you have added to your S3 bucket.
Concerns
- By default CloudFront requires clients that support SNI. In order to add custom IPs to support legacy clients, AWS charges $600/month.
- The maximum response time CloudFront supports before responding to the client with a 504 is 60 seconds. In order to support this, we had to tweak a request made in staging environments.
- Upon testing, we found that changes to the origin could take up to 5 minutes to propagate to edge nodes.
- CloudFront does not currently support WebSockets.
Deploying a few EC2 instances running HAProxy or Nginx could have solved all of the mentioned issues but would have left us managing an entirely new cluster. We decided the operational overhead of this was not worthwhile.
Consequences
During a recent cluster upgrade, there were no reports of broken IP addresses. In the past, we would have had to update user-facing DNS records which resulted in clients seeing error pages when a DNS cache, either on their machine or somewhere between our nameservers and their machine, became stale. Flushing Google's DNS cache helped resolve some of these issues, but obviously not all.
Our thinking
Why Moving to Better Was The Right Career Move for Me
Having experienced the long, confusing mortgage process recently myself, I was drawn to Better as soon as I heard about them. I could see the huge opportunity in front of this company that was leveraging modern technology and automation to revolutionize the mortgage industry. I wanted to be part of it. Innovation has always been my biggest motivation. Getting the chance to have a real impact in an organization like Better and helping them grow and succeed, was exciting. I left Google in early 2020 to join my new company as Engineering Manager, and below I’m sharing why it’s been such a great decision for me.Tue Aug 31 2021—by Nick Zukoski3 min readI gave the business what they asked for and they never used it
An addition to the long list of unused ML projectsMon Jun 29 2020—by Kenny Ning3 min read- data
- ML
- project management
Engineering a Diverse Team: Taffy Chen and Jimmy Farillo
Software engineers Taffy Chen and Jimmy Farillo launch a new blog series to showcase different perspectives on the Better engineering team, and the ways they’re working to make it even more diverse and inclusive.Fri May 14 2021—by Taffy Chen and Jimmy Farillo2 min read- diversity
- inclusion
- perspectives