How to host a static website using AWS S3 and Cloudflare
I’ve been noticing a previous post about how to host a static site using various AWS services has been gaining in popularity.
Most recently a blog post by Thom Greene (@tbgree00) had mentioned the previous article and while all the steps in the previous post are accurate and works – I wanted to share how I now host static websites using AWS S3 and Cloudflare.
But first, why the change? It’s a simpler process.
In the previous post several AWS services (Route 53, Cloudfront, & Cert Manager) was needed to do what Cloudflare does by itself. It’s also cheaper as there is a cost that comes with Route 53 and Cloudfront, whereas Cloudflare is FREE.
It is more secure. In the previous post we created an S3 bucket and gave it public read access, using the process detailed below the bucket is no longer publicly accessible and only accessible if coming through Cloudflare. This ensures no one can try to side step all the protections that Cloudflare offers when trying to reach my static sites.
Requirements before getting started:
- An Amazon Web Services account.
- Domain name – I use and suggest either Namecheap or NameSilo to register new domains if you haven’t already. (Use coupon SAVE1OFFNAMESILO at NameSilo to save $1.00)
- Already have a static HTML page designed and ready to upload.
Host a static website using AWS S3 and Cloudflare
Amazon S3 Bucket Setup
- First create an AWS S3 bucket with the same name as your domain name, be sure to include the www. and select your desired AWS region.
- In Step 3, Set Permissions, of creating the S3 bucket make sure to UN-check the “Block all public access” checkbox and confirm you want to remove this block!
- Then enable static website hosting for the bucket under the Properties tab.
and set an index and error document file names and click SAVE. Be sure to make note of the bucket endpoint URL
- To allow this bucket to be accessible via Cloudflare we will need to edit the bucket policy, under the permissions taband copy/paste the following:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::www.MYDOMAINNAME.com/*", "Condition": { "IpAddress": { "aws:SourceIp": [ "2400:cb00::/32", "2405:8100::/32", "2405:b500::/32", "2606:4700::/32", "2803:f800::/32", "2a06:98c0::/29", "2c0f:f248::/32", "103.21.244.0/22", "103.22.200.0/22", "103.31.4.0/22", "104.16.0.0/13", "104.24.0.0/14", "108.162.192.0/18", "131.0.72.0/22", "141.101.64.0/18", "162.158.0.0/15", "172.64.0.0/13", "173.245.48.0/20", "188.114.96.0/20", "190.93.240.0/20", "197.234.240.0/22", "198.41.128.0/17" ] } } } ] }
Note: Be sure to replace MYDOMAINNAME in the policy with your own domain name.
- Once you’ve saved the above policy, you will get a message from AWS stating the bucket has public access. This is OKAY. In fact, while the bucket is technically public, it’s only accessible if coming through Cloudflare. Hence the extra security.
- You can now upload your static website to your S3 bucket.
Note: Your website will not be accessible yet.
AWS S3 non-www bucket setup
We need to create a second S3 bucket so that when users try to access domainname.com they will be redirected to www.domainname.com.
- Create a second S3 bucket with the same name as your domain name, this one WITHOUT the www.
- Enable static website hosting for the bucket, but this time set it to redirect to your www.domainname.com bucket.
That’s it for the second bucket, now lets setup Cloudflare!
Cloudflare Setup for your static HTML site
- Log into Cloudflare and click on “+Add Site“.
Then type in your domain name and click on “Add Site“.
- Then select the FREE Cloudflare plan. Feel free to use another plan if you feel you need it.
- Next you may have one or more DNS records associated with your domain, if so remove them by clicking on the X next to each one of them.
- Now lets add some DNS records for our two AWS S3 buckets. We need to add a record for each S3 bucket.
- Create a CNAME record with the name www and for the server field enter the www.yourdomain.com bucket endpoint URL without the https://
- Create a second CNAME record with the name of your domain (without the www.) and for it’s server field enter the yourdomain.com bucket endpoint URL, also without the https://
- Cloudflare will then give you two nameservers to point your domain name to. So now log into your domain name registar and update the name servers to the nameservers Cloudflare gives you.
- Finally, change the default Cloudflare SSL/TLS encryption option from “Full” to “Flexible“. I also prefer to enable “Always use HTTPS” as well.
At this point you’ll just need to wait for DNS to update. This could potentially take 24-48 hours, but in most cases this is much faster.
There you have it, you now have a static website being hosted on S3 and the protections and speed improvements from Cloudflare.