- CDNs are not cheap. Explore primary design considerations to determine if a CDN is needed for the system we are designing.
- Explore CloudFront features.
- Host a secure static website on S3. Explore the default certificate provided by CloudFront.
- Provision a custom SSL certificate using ACM and use it with a custom domain name integrating with Route 53.
- Use Origin Access Control to restrict access to the S3 bucket so that only CloudFront can access it.
Important considerations for deciding if a content delivery network is needed for the system we are designing:
- Does the system have user presence across the globe?
- What type of delivery is needed for the workflow? Only dynamic? Only static, or a combination of both?
- What are the approximate sizes of objects delivered?
- Is any object transformation needed?
- What are the security and access considerations for the content being served?
These are some primary design considerations, however there could be many more. If our requirements justify the need for a CDN, then AWS CloudFront is a possible solution.
CloudFront is a content delivery network. It's job is to improve the delivery of that content from it's original location to the viewers of that data. It does that by using caching and by using a global delivery network of edge locations. Content is cached in these edge locations until their TTL expires or until a new origin fetch is done as a result of a new deployment or a cache invalidation.
Key components:
- Origin is where the original, definitive version of our content is stored. It can be S3 or a custom origin like a webserver that has a publicly routable IPV4 IP address. You could have one or more origins for a CloudFront distribution, upto 25 currently.
- Distribution is the configurable unit of CloudFront. To use CloudFront, we create a distribution and this gets deployed to the network.
- Edge location is where our information is cached. Edge locations are part of CloudFront's global network and are located in major AWS Regions and major country and state capitals. Edge locations are closer to our end users.
- Regional Edge Cache provides another layer of caching. They are much bigger than Edge locations and are fewer in number. They are used to cache large amounts of less frequently accessed data, in larger more global CloudFornt deployments.
- Cache behavior settings allow us to configure CloudFront functionality based on our application needs. A distribution comes with a default cache behavior, we can create additional cache behaviors that define how CloudFront responds when it receives a request for objects that match for e.g a particular path pattern.
- APIs or applications can be delivered over HTTPS using the latest version of TLS to encrypt and secure communication between the viewers and CloudFront. AWS Certificate Manager (ACM) can be used to create a custom SSL certificate and deploy to an CloudFront distribution for free.
- Protection against network and application layer attacks is provided by CloudFront by seamlessly integrating with AWS Shield, AWS Web Application Firewall (WAF), and Amazon Route 53. This creates a flexible, layered security perimeter against multiple types of attacks including network and application layer DDoS attacks.
- Access to content can be restricted using a number of mechanisms like Signed URLs and Signed Cookies. It is possible to restrict access to only authenticated viewers using Token Authentication. Users in certain geographic regions can be restricted access to content through CloudFront's geo-restriction capability. Securing an S3 website origin, making it only accessible from CloudFront is possible using using Origin Access Identity, now referred to as Origin Access Control.
- CloudFront infrastructure and processes are compliant with industry standards like PCI-DSS Level 1, HIPAA, and ISO 9001 FEDRAMP etc.
- CloudFront is a pay-per-use offering, requiring no long term commitments or minimum fees. After the free tier, cost varies depending on the amout of data transfered to the internet and to the origin per GB.
- Lambda@Edge makes it possible to run Node.js and Python Lambda functions to customize content that CloudFront delivers. Here the functions are executed closer to the viewer, in response to CloudFront events without the need for provisioning or managing servers.
Note: As a prerequisite for this hands-on we need a public hosted zone on Route 53. The focus of this exercise is to host a secure static S3 website, configure a custom domain name and to restrict access to the content to CloudFront. Lamda@Edge will be the focus of a future hands on exercise.
- Deploy static website using the cloud formation template. Details
- Test the S3 website. Notice that if the protocol in the url is modified to https, it will keep spinning and will not load. Details
- Create a new CloudFront distribution using the S3 website as Origin. Details
- Load the distribution endpoint on a browser, notice the padlock which indicates it is using https, view the certificate. Details
- Modify the distribution by adding a custom DNS name. For this step and subsequent steps we need a public hosted zone in Route 53. Details
- Request a custom SSL certificate using ACM and attach it to the CloudFront distribution. Details
- In Route 53 create an A record pointing the custom domain name to the CloudFront distribution. Details
- Load the custom domain name on a browser, notice the padlock and view the name on the certificate matching the custom domain name. Details
- Modify the distribution by restricting public access. Details
- Update bucket policy so that only the CloudFront distribution can access the bucket. Details
- Let's understand what the bucket policy means. Details
- Load the S3 static website URL on a browser and notice the 403 HTTP Status code. It can only be accessed by the CloudFront distribution. Details
- Clean up resources.
Deploy static S3 website using the CloudFormation template here.
After the Stack has been created, copy the static website url from CloudFormation Outputs section.
Load it in a browser window to make sure it is working.
Notice that it is unsecure.
If we try https, it will not load - it will simply spin.
We are going to change this.
On the AWS Admin console, go to CloudFormation, click on Create New Distribution.
Select the Static S3 website endpoint from the drop down as the origin.
For Viewer protocol policy, select HTTP & HTTPS
Restrict Viewer access - no
Caching Policy as CacheOptimized
Under Security settings, select Do not enable security protections.
There is no need for an SSL certificate because CloudFront will assign a default certificate.
Click on Create Distribution.
Wait until the distribution is created and has completed deployment.
Copy the URL of the distribution.
Load the url on a browser and notice the padlock on the URL. Observe the default SSL certificate provided by cloudfront.
Inspect the Route 53 public hosted zone. In the public zone we only have the NS and SOA records.
To add a custom DNS name to the distribution, edit the distribution.
Enter the chosen DNS name. Click on Request certificate.
In the Certificate Manager screen enter the fully qualified domain name. Make sure DNS validation is selected.
Click on Create records in Route 53.
Route 53 will create a new CNAME record in our public hosted zone. This is how Route 53 validates that we own the domain.
Now check the Route 53 hosted zone. The new record has been created by Route 53. DNS validation has been completed successfully.
Return to CloudFront to edit the distribution. Now the new SSL certificate shows up in the drop down. Select it and save the changes.
Wait for the distribution to be updated and deployed. Notice that the custom DNS name and the cert name are displayed.
In Route 53 create an A record pointing the custom domain name to the CloudFront distribution.
Load the custom DNS name. Inspect the padlock and observe the custom SSL cert we created.
Now we need to restrict access to the S3 site so that only CloudFront can access it. This ensures security of our application.
In the distribution, click on Origin. Select the origin and click on Edit.
Now we are going to modify the Origin access.
From Public, change it to Origin access control settings (recommended)
Click on Create Origin Access Setting and then Create control setting. Keep the defaults and click on Create.
Now the control setting that was just created appears on the drop down.
We need to now modify the Bucket policy on our S3 bucket so that only CloudFront can access it.
In S3, paste the copied bucket policy. Make sure the bucket name and distribution name matches ours. If not, edit it. Save the policy.
Understand what the policy means.
A GetObject operation is allowed on our bucket by the CloudFront service, as long as the source arn of the distribution matches ours.
After setting up Origin Access Control, if we try our original S3 website URL we see that it can't be accessed.
It can only be accessed using CloudFront. This means that we have prevented unauthorized access to our content.
Clean up resources. Delete the bucket, delete the Distribution. delete the Record in Route 53.