SCC

Brasil

os cloud gurus

Software Cloud Consulting

Your software development, cloud, consulting & shoring company

AWS Cloudfront


7

Introduction


AWS Cloudfront is a content delivery network (CDN) service that securely delivers data, videos, applications, and APIs to customers globally with low latency, high transfer speeds, all within a developer-friendly environment. Configuring CloudFront with S3 is a common use case, and it's a good practice to use CloudFront to cache the objects in your S3 bucket, reducing the latency and the costs of the requests to your S3 bucket.

This initial configuration is simple, you just need to create a CloudFront distribution and configure the S3 bucket as the origin, and configure the cache behavior to cache the objects in the S3 bucket. Normally, you let the objects in the S3 bucket public, and configure the bucket policy to allow the CloudFront distribution to access the objects.

4
Simple diagram of a Cloudfront distribution with a S3 bucket as origin.

If you use the AWS console UI to create the CloudFront distribution, you can easily configure the S3 bucket as the origin, but the default options are not secure, and there is some other details that can pass unnoticed.


Error pages configuration



If your s3 bucket has a frontend code of your app, and this frontend code is a react type(react router deliver the page on index.html), you need to configure the error pages in the CloudFront distribution, to redirect the user to the index.html when the user tries to access a page that doesn't exist.
The normal configuration on this case is like this:
4


Cache Invalidations



If you are new to Cloudfront, the cache invalidations can be a little bit confusing, because the invalidations are not immediate, when you change files in your origin, or configurations, you need to invalidate the cache, so the updated content is delivered to the users.
You can do the invalidations in the UI giving the path of the object that you want to invalidate,(use /* as path to invalidate all objects) or you can use the AWS CLI to do this.

Multiple S3 Origins and Origin Access Control


Make this configuration secure and accross multiple S3 buckets is a challenge, there is lot of configurations and variations of cache policies, origins, behaviours, etc.

Checkout our git repository with an example of deploying a CloudFront distribution with OAC, and multiple S3 Origins, using CloudFormation.
Github repo with CloudFormation code to deploy this example.
In the example, we have two origins, one for the frontend code and another for the assets. The path pattern for the frontend code is / and for the assets is /assets/*.

4
Improving the security of the structure implementing Origin Access Control and two separate buckets as origins for different use cases.

Multiple S3 Origins


Cloudfront supports various origins, including S3, EC2, ELB, and custom origins. In this article, we will focus on S3 origins. This is a common scenario when you have two buckets, one for your frontend code and another for assets, uploaded by the users of your application.

In addition to the basic setup, it's important to understand that each S3 origin in CloudFront can have its own unique configuration settings. These settings include the origin ID, domain name, origin path, origin access identity, and more. Each of these settings plays a crucial role in how CloudFront interacts with the S3 bucket.

Path's configurations


The way that CloudFront decides which origin to use is based on the path pattern. In the behavior of your CloudFront distribution, you can define a path pattern for each origin, and CloudFront will use the origin that matches the path pattern.

Also in the origin configuration, you can define the path in your S3 bucket that CloudFront will use to get the objects. These two configurations can cause confusion, so be careful when defining the path pattern in the CacheBehaviour (this is related to your URL, and can be related to specific file types like /*.png)
and the path in the origin configuration (this is related to the path in your S3 bucket where the objects are stored).

It's worth noting that the path pattern in the CacheBehaviour is a string that lets you specify one or more files that you want CloudFront to deliver to viewers. You can use wildcard characters to specify multiple files.

Managed cache policies


Finally, the cache policy and the origin request policy are two configurations that can be used to define the cache and the request behavior of your CloudFront distribution.

AWS provides some AWS managed cache policies that you can use, or you can create your own policies. In the example, we are using an AWS managed cache policy. To use this policy in CloudFormation, you have to include the ID of the managed policy. This ID can be found in the AWS documentation on using cache managed policies.

Cache policies determine the values that CloudFront includes in a request that it sends to the origin. These values can include headers, cookies, and URL query strings. Cache policies also determine the objects that CloudFront caches and how long those objects stay in the cache.

Origin Access Control


Usually when a application is new and small we tend to relax the storage configuration, for example not implementing correct storage tiering,
and implementing bucket policies that allow all the objects to be public, don't configure correcly the CORS, and so on.
As your application grows, you must start implementing some best practices, one of the most common is implement cloudfront, to cache the objects and reduce the latency,
And one of the steps to implement cloudfront is to configure the Origin Access Identity (OAI) or Origin Access Control (OAC).

Until 2022, aws supply the OAI, that is a special cloudfront user that you can associate with your distribution,
and this user has permission to access the objects in your S3 bucket, giving you the ability to restrict access to your objects,
and also to use the bucket policy to allow only the cloudfront distribution to access the objects.

Since 2022, aws supply the OAC, OAC strengthens security with short-term credentials and more frequent credential rotations compared to OAI. It also allows for granular policy configurations through resource-based policies, providing better protection against confused deputy attacks.

The Evolution from OAI to OAC


While OAI offered a secure way to connect S3 origins to CloudFront, it fell short in supporting granular policy configurations,
HTTP and HTTPS requests using the POST method in AWS regions requiring AWS Signature Version 4 (SigV4), and integration
with Server-Side Encryption with AWS Key Management Service (SSE-KMS). OAC addresses these limitations and introduces several notable enhancements.

Configuring OAC for an Existing CloudFront Distribution


To configure OAC, sign in to the AWS Management Console and navigate to the CloudFront console. Select a distribution
from the list and choose the S3 origin you wish to associate with an origin access control setting under the Origins tab.
If the origin is public or uses OAI, it will show as such. To use OAC, select "Origin access control settings" and choose
an existing origin access control or create a new control setting with one of three signing options.

Updating an Existing Distribution


When updating a distribution, it's crucial to modify the S3 policy to permit the CloudFront IAM service principal and your
distribution resource to access the S3 bucket. We recommend updating the policy to allow access to both OAI and OAC before
saving the origin configuration, effectively reducing service downtime to zero.

                    {
                        "Version": "2012-10-17",
                        "Statement": [
                            {
                                "Sid": "AllowCloudFrontServicePrincipalReadOnly",
                                "Effect": "Allow",
                                "Principal": {
                                    "Service": "cloudfront.amazonaws.com"
                                },
                                "Action": "s3:GetObject",
                                "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*",
                                "Condition": {
                                    "StringEquals": {
                                        "AWS:SourceArn": "arn:aws:cloudfront::ACCOUNT_ID:distribution/DISTRIBUTION_ID"
                                    }
                                }
                            },
                            {
                                "Sid": "AllowLegacyOAIReadOnly",
                                "Effect": "Allow",
                                "Principal": {
                                    "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EH1HDMB1FH2TC"
                                },
                                "Action": "s3:GetObject",
                                "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
                            }
                        ]
                    }
                    

Advantages of OAC


OAC is designed with enhanced security practices such as short-term credentials, frequent credential rotations, and
resource-based policies, providing stronger security for your distributions and better protection against confused
deputy attacks. It supports all HTTP methods, including GET, PUT, POST, PATCH, DELETE, OPTIONS, and HEAD.
OAC also supports downloading and uploading S3 objects encrypted with SSE-KMS. Furthermore,
OAC allows access to S3 in all AWS regions, including existing and future regions, unlike OAI,
which will only be supported in existing AWS regions and regions launched before December 2022.

Conclusions


CloudFront is a powerful service that can be used to cache the objects and reduce latency in your app, but it requires attention to detail to configure it correctly.
The initial configuration is simple, but there are some details that can pass unnoticed, error pages, cache invalidations, and the security of the origins.
Following this practices and undestanding the details of the configurations, you can improve the security and the performance of your app.

  • Back to Blog Overview
  • Autor


    ...

    Daniel do Nascimento

    AWS Developer

    3 x AWS Certified