25.1 CloudFront Distributions: Web vs RTMP, Price Classes, and Edge Locations
Right, let’s talk about CloudFront distributions. This is where you stop thinking of CloudFront as a magic box and start treating it like the complex, configurable beast it is. The first thing you’ll hit when you create one in the console is a choice that seems bafflingly ancient: Web or RTMP. Let’s be direct: you almost certainly want “Web Distribution.” It’s for the modern web—HTTP(S) traffic, your website, your APIs, your static assets. RTMP is a relic, a streaming protocol from the Adobe Flash era. AWS still offers it because, well, someone somewhere is still running a Flash-based video service and paying them a fortune for the privilege. It’s the technical equivalent of a museum exhibit. Let’s move on.
Web Distribution: The Main Event
A Web Distribution is your standard CDN configuration. You point it at an origin (like an S3 bucket or your crusty old EC2 server), and CloudFront sits in front of it, caching content at its Edge Locations worldwide. The real genius—and complexity—is in the Behaviors. Think of a behavior as a rule: “For requests that look like this, do that.” You can have many behaviors, and they’re evaluated in order, first match wins. This is how you get fancy: cache your static images for a year, don’t cache your API endpoints at all, and password-protect that one weird staging directory. It’s your traffic cop.
The Price of Speed: Price Classes
This is one of those settings you might gloss over, but your finance department will care about later. CloudFront has Price Classes to help you manage cost versus performance.
- Price Class All: Uses all Edge Locations. Best performance, global reach, highest cost. Use this if you have a truly global audience and your content is latency-sensitive (it probably is).
- Price Class 200: Uses only the most common, and therefore cheaper, locations. Covers most of the planet but excludes the more expensive, sparsely populated edges. This is the sensible default for most applications. The performance hit is negligible for most users.
- Price Class 100: The budget option. Only uses the cheapest edges, which are generally in North America and Europe. If you’re only serving those regions, fine. If not, don’t be that person who makes a user in Sydney wait an extra 300ms to save a fraction of a cent.
Choose wisely. You can’t change the Price Class after creation, which is a fantastically annoying limitation. You have to create a new distribution and update your DNS. Thanks for that, AWS.
Where the Magic Happens: Edge Locations
These aren’t AWS regions; they’re hundreds of points of presence (POPs) in major cities worldwide, run by AWS and its partners. When a user requests your logo, cat-pic.jpg, CloudFront doesn’t trek back to the US-east-1 origin server every single time. It serves it from the Edge Location geographically closest to your user. The first time it’s fetched from the origin (cache miss), but every subsequent request for that object (until it expires) is a blazingly fast cache hit from the edge.
Here’s the kicker: you don’t get to pick specific edge locations. You configure your distribution, and AWS’s systems handle the routing. Your only lever here is the Price Class, which indirectly controls which subset of the network is used.
Creating a Distribution: The CLI Way
The AWS console wizard is fine, but it hides the details. Let’s use the CLI to see what’s actually going on. This command creates a bare-bones distribution pointing to an S3 bucket. Notice the PriceClass and ViewerProtocolPolicy settings.
aws cloudfront create-distribution \
--distribution-config file://dist-config.json
And the dist-config.json file:
{
"CallerReference": "my-unique-ref-2024-06-15",
"Aliases": {
"Quantity": 0
},
"DefaultRootObject": "index.html",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "my-s3-origin",
"DomainName": "my-bucket.s3.amazonaws.com",
"S3OriginConfig": {
"OriginAccessIdentity": ""
}
}
]
},
"DefaultCacheBehavior": {
"TargetOriginId": "my-s3-origin",
"ViewerProtocolPolicy": "redirect-to-https",
"MinTTL": 0,
"ForwardedValues": {
"QueryString": false,
"Cookies": { "Forward": "none" }
},
"TrustedSigners": { "Quantity": 0, "Enabled": false }
},
"Comment": "My production distribution",
"Enabled": true,
"PriceClass": "PriceClass_200"
}
The CallerReference is crucial—it must be unique every time you call this, or it will fail. It’s a sanity check to prevent duplicate operations. The ViewerProtocolPolicy set to redirect-to-https is a best practice; it forces everyone onto HTTPS without you having to think about it. And ForwardedValues is a common pitfall: if you set QueryString to true, you’re telling CloudFront to cache every unique URL separately. https://example.com/cat.jpg?user_id=123 and ...?user_id=124 become two different cached objects. This can murder your cache hit ratio if you don’t need it. Only enable it for query strings your origin server actually uses to generate unique content.