When creating a CloudFront implementation, sites are registered with CloudFront using configuration objects called distributions. Origins and all other configuration items are stored in the distributions.
The CloudFront distributions will be assigned a DNS name by AWS that uses the cloudfront.net domain. We can then map our own domain name to the distribution by creating a CNAME record in DNS that references the AWS CloudFront domain name. When connecting to the URL, connections are directed to the nearest location that can provide the best performance and not back to the origin, which may be on the other side of the world.
Origin redundancy can be configured to use a backup to your primary source of data. If your main source origin fails, a failover can occur based on HTTP status codes such as the 400 and 500 series. Both AWS hosted and on-premise origins are supported and will back up each other based on the design requirements.
Creating a CloudFront distribution can be done from API calls, with the AWS command-line interface, with the AWS web graphical user interface, or as infrastructure as code using CloudFormation.
Route 53 is the AWS DNS service. CloudFront domains will always use the cloudfront.net DNS name by default. However, you can use CNAME pointers to map your company DNS name to the CloudFront distribution DNS for clarity. Also, Route 53 supports the mapping of zone apex names free of charge. This allows you to map a top domain such as helloworld.com to your CloudFront distribution such as abcdef12345678.cloudfront.net.
There is also a regional CloudFront component that contains less frequently accessed data and has a larger storage capacity than edge locations. Regional edge caches serve content to a subset of the edge locations. Regional edges have larger cache storage capacities and longer retention times than the smaller edge locations. This way, if the content should time out on the edge storage sites because of the data not being requested for a period of time, the edge location does not have to request the data from the origin. Instead, the edge will query the regional edge cache, and if the data is stored in the regional cache, then it is returned to the edge with a faster response than having to retrieve the information from the origin. If the data is not in the regional cache, then a regional fetch is performed to pull the object from the origin to the CloudFront regional cache and on to the edge location. Figure 1.3 shows how the regional edge servers provide cached data closer to the edge locations.
When a user makes a request, DNS will route them to the nearest edge location to serve the content. If this is the first request or if there has not been a request for the time-out period, there will be a cache miss. In this case, CloudFront will go back to the origin if it is S3 data or regional cache to retrieve all the other data. The data is delivered to the end user and stored locally in the edge cache. Any new requests at this location will be serviced quickly as the data is now stored at the CloudFront edge location. Figure 1.4 shows the traffic flow.
FIGURE 1.3 AWS CloudFront regional edge nodes
FIGURE 1.4 Caching data at CloudFront edge locations
Data retention in the edge cache has a default value of 24 hours. It is a best practice to have a longer retention time if the content does not change very often and to use a versioning system to track updates to objects. If the edge receives a user request for an object that has been cached for more than 24 hours, the origin is checked to see if the content has changed. If it has, the new object will be uploaded and the expiration timer set back to the TTL value. File cache control headers are used to instruct the edge location on how often to check for a new object version at the origin or regional cache. If it is S3, then the origin location will be checked; however, for other content, the regional cache is checked first. If the value of the cache control header is 0, then the check for a newer object is made for every request.
Each edge location views an object as current if it is within its time-to-live (TTL) range. When the TTL of an object stored in an edge location counts down to zero, it becomes stale but is not deleted from its local cache. Instead, the edge checks with the origin to see if there is an updated version of the object. If the origin returns a response code of 304 Not Modified, the edge location marks the locally stored object as current. If there is a newer version, the origin will forward the data to the edge to replace the stale data stored locally and flagged as current data. The default validity period is defined for each distribution with the default value set at 24 hours. Per-object TTL values can be defined for an object that will override the default of 24 hours. There are also minimum and maximum TTL values that can be configured per distribution that set absolute high and low values that cannot be exceeded when configuring TTL values, either default or custom.
HTTP headers can be configured to control the TTL values when making a request. The Cache-Control max-age (seconds) and Cache-Control s-max-age (seconds) defines the TTL for the object, and both serve the same function. Next is the Expires (date and time) header, which is self-explanatory. As we discussed, the values that are defined either in seconds or as a date-time format are limited by the minimum and maximum age global TTL values. If the header values are below the minimum or maximum timers, then the default is used, either high or low. The headers are defined differently depending on the origin being used. If the origin is an S3 bucket, then the values are stored in the object metadata. The second option is to have the application or web server insert the values.