AWS - How to use S3 as a subdomain for static files/assets
Tags: aws, cloudfront, cloudflare, s3
Published: 2023-10-27 21:33:18

Alright, it's fairly easy to setup S3 and configure it as a static site and put your statis website on it, but to point a real domain to it you can't get HTTPS [SSL certificate] working properly on it unless you follow these instructions:

https://docs.aws.amazon.com/AmazonS3/latest/userguide/website-hosting-custom-domain-walkthrough.html#website-hosting-custom-domain-walkthrough-domain-registry

TL;DR on that is that it's a list of 12 steps [each one its own page] that requires you to setup two S3 buckets, use Route53 for the domain, setup Cloudfront and then get a certificate through the ACM (AWS Certificate Manager) in order to get HTTPS working on subdomain.yourdomain.com

So, here's a faster, simpler, and better performing way. 

Before we continue be sure you know the difference between "Cloudfront - an AWS service" and "Cloudflare - a separate CDN service"

We all use cloudflare.com for caching, free ssl, free CDN, free bot protection and more...right right? You don't? Get on it. 

My steps are as follows:
- Get on S3, setup your bucket with the name of the subdomain, eg your bucket name should literally be "subdomain.yourdomain.com"
- Give it "public access" [ignore the warnings]
- Go to the "permissions" tab and make sure Block all public access is "off"
- On that same tab find the "Bucket Policy" and set a Policy for access, so it's not public and only your domain.com can access it, like so:

`{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Dont Show List",
            "Effect": "Deny",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::subdomain.yourdomain.com",
            "Condition": {
                "StringLike": {
                    "s3:prefix": "/*"
                }
            }
        },
        {
            "Sid": "Allow your domain access",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::subdomain.yourdomain.com/*",
            "Condition": {
                "StringLike": {
                    "aws:Referer": "https://domain.com/*"
                }
            }
        }
    ]
}`

Note: this will now allow anyone to list the contents of your bucket and will only allow requests to load files come from your domain [via HTTPS only]

Next:
- Register your domain anywhere
- Point your domain to cloudflare.com [their walkthrough is simple as heck]
- Add a CNAME for your subdomain to point to the S3 URL which will be something like "subdomain.yourdomain.com.org.s3.us-east-1.amazonaws.com"

That's it. Your subdomain will now load your assets from S3, cache them via Cloudflare which automatically handles the SSL for you so HTTPS works out of the box, plus Cloudflare caches your assets [which performs faster than regular S3 requests] and your site's gonna be pretty damn fast.

This is great for sites with lots of mp4s or large images they need hosted. Not only does it perform better than standard S3 requests, it also costs less because you don't have to pay for Cloudfront and the bandwidth usage on S3 is lessened by having Cloudflare do the caching. 

P.S. I wrote this shortly after implementing this again today, so i may have missed an item, if you run into trouble setting this up, please reach out to me, I'll be glad to update this with more thorough details to help others out in the long run.

End result, i applied this switch on Oct 27th [the last 3 days on the chart] as a result client now pays $0 for cloudfront. Before it was costing them nearly $20-$30/day.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/agrnhhdswbtioltyqs40.png)