Protect your API using AWS Cloudfront
Add caching, security and more to your AWS Application Load Balancer
A while ago, I was studying for the Software Architect Associate certification when I discovered that Cloudfront could be used in front of an Application Load Balancer(ALB)1. And that did blow my mind.
Every time that I think about Cloudfront, I consider of it as the starter pack of S3+Cloudfront to work as a CDN for front end services.
However, the discovery of using it in front of an ALB triggered my curiosity to discover what would be the advantages of it. And here is the result of this study. =)
Caching requests
When we think of a CDN, we think of caching data that doesn’t change frequently on the edge of the web to deliver content fast for the user. So the first use-case of Cloudfront in front of an ALB would be caching GET requests to the server.
We can cache the data that is requested using query strings. Here you need to assume how much of eventual consistency you are allowed to have, until the TTL of the cache expires. The main point is to always use the query strings in the same structure. Because a request with cloudfront.net/main?foo=bar&bar=foo
will be in a different cache than cloudfront.net/main?bar=foo&foo=bar
.
There’s a more nuanced configuration that you can do on cloudfront to handle the caching, and you can check them on the docs.
Protect your ALB
The second use case is to use the power of Cloudfront to avoid interruptions in your service. We can configure the ALB to only accept requests that origins only from Cloudfront using a custom header on the request. This header will be added into the configuration of Cloudfront, and to the load balancer condition rule for routing the request. With this, only requests that are from Cloudfront are directed to your servers. However, your LB will still be open to the web and can receive requests from any server and return a 403.
To fix that, you can attach a Managed IP Prefix List of Cloudfront2 as the source of the security group of the load balancer, making sure that only the requests that origins in Cloudfront access your Load Balancer. With this in place, we make sure that unwanted requests will not reach the load balancer and that our bill will be kept tight.
Check wich other services are supported within the AWS-manager prefix lists here.
Improve Performance on Handshake
This one is not stated in the docs, and I’ve got it from a blog post from StormIT3. In the post, they state that the handshake between the client and Cloudfront(~20ms) is thousands of milliseconds quicker than the handshake between the client and the Load Balancer(~700ms). This happens because Cloudfront tries to maintain the connection to the origin open for several seconds in case another request arrives. This save time on re-establishing new TCP connections to the Origin and the subsequent handshakes. Plus, this blog post from 2017, also states that Cloudfront connections to AWS origins are routed over the private backbone networking, which also improves reliability and performance.
Enhanced Security
Out of the box, Cloudfront offers geolocation restriction, that helps you to limit where your content will be available. We can also leverage AWS Shield and AWS WAF for increased security. Thus protecting our application of unwanted traffic. Here we also have a first benefit of Cost, where the pricing of AWS Shield Advanced is twice as low when the resource protect is Cloudfront compared when it’s used to an ALB4.
Cost
YOU SHOULD ALWAYS THINK ABOUT COST.
With that said, normally I don’t keep an eye on cost about network traffic, since most of the resources that I have are using internally on AWS network. However, after this study, I’ll start to look more closely.
The metric that we should look forward to evaluating is the Data Transfer Out(DTO). DTO is how much of the data we transferred out of AWS, and that’s a metric that has a cost.
Cloudfront offers 1 TB per month in the free-tier for data transferred out of it. With all the data transferred between the ALB to CloudFront having no cost, since it’s inside AWS network (as we saw on the second topic), we eliminate the cost of it. And as everything in AWS, the more you use, the cheap it gets.
As we also have economy on the handshake between Cloudfront and the ALB, we also reduce the cost of the ALB LCU (it’s a dimension between: new connections, active connections, processed bytes and rule evaluations).
Conclusion
Cloudfront for sure will be my to-go option when designing new API’s that will receive public traffic. All the features and benefits listed here are only possible for ALB that are internet-facing. I wasn’t expecting these many benefits for an increased cost economy, and it’s a good trade-off if you ask me.
Of course, all the points described should be evaluated to ensure the best cost-benefit for the company. Because security services like AWS Shield and WAF can be a bit expensive. However, only leveraging Cloudfront already gives you a good foundation to offer the best performance for your costumers.
That’s all for today, folks!
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistS3AndCustomOrigins.html#concept_elb_origin
This sure is something that should be stated in the Cloudfront docs and not forwarded to a blog post. =/ https://aws.amazon.com/blogs/networking-and-content-delivery/limit-access-to-your-origins-using-the-aws-managed-prefix-list-for-amazon-cloudfront/
https://www.stormit.cloud/blog/cloudfront-distribution-for-amazon-ec2-alb/
https://aws.amazon.com/blogs/networking-and-content-delivery/accelerate-protect-and-make-dynamic-workloads-delivery-cost-efficient-with-amazon-cloudfront/