Advantages of S3 & CloudFront
The Cost of a Slow Website
We’ve all come across websites that load so painfully slow that our patience wears thin and we end up hitting the back button. It’s bad for us because we couldn’t get to the content we were expecting; it’s bad for the business owner because they just lost traffic and a potential conversion.
Speed It Up With Amazon’s S3 & CloudFront
- Unlimited storage & fast server response. Since you’ll be running your website on a content delivery network (CDN) with edges all over the world, server response time should be top notch. This includes both your assets (images, style sheets, etc) as well as your page’s html code.
- No server overhead or maintenance. YES!!! Nothing puts a damper on my day like having to deal with unexpected server admin issues that gobble up hours of time. Since S3 is not a web server per se, you can forget about this issue. (There is a caveat, but we’ll cover that in a bit.)
- AWS’ S3/CloudFront comes with free SSL and virtually no security issues. Not much else to say about that, other than, because it’s not a traditional web server, the only security issue is access to S3 buckets. And these are easily locked down.
What About WordPress?
So, there is one caveat. This works only for static websites because S3 does not provide the capability to run any server side code, such as PHP, .net or Java. Therefore, if you are running a WordPress website, a web store or any other website that requires significant processing, you will not be able to take advantage of this without creating an external service or utilizing some sort of microservice. You will need to convert your site to a static one and convert any user interaction components that require server processing – such as contact forms – to a different system. See the dynamic website functionality section for some ideas.
What We’re Doing Today
Today we will go over the process of setting up and hosting a website on Amazon’s S3. We will also utilize Amazon’s CloudFront CDN so that we can distribute html files and assets to multiple geographically diverse edge locations, which will result in much faster overall download times. To accomplish this, we will also employ Route 53 for DNS management and AWS Certificate Manager for SSL certificates.
For Your Convenience…
- Create bucket to hold website files (www version of domain)
- Configure bucket properties
- Configure bucket permissions
- Upload files
- Create bucket for 301 redirection (non-www version of the domain)
- Configure 2nd bucket properties
- Configure 2nd bucket permissions
- Set up Route 53 DNS
- Install SSL for naked domain
- Install SSL for www domain
- Create distribution for naked domain
- Create distribution for www domain
- Set up “A” record for naked domain
- Set up “A” record for www domain
S3 buckets
www bucket
non-www (naked domain) bucket
SSL
CloudFront
Route 53
Step 1: Setting Up S3 for Static Website Hosting
Create an Amazon S3 Bucket for the www domain
Create Bucket
- In your AWS admin panel, go to “Services” -> “S3” -> “Create bucket”.
- Enter your bucket name, region and click “Next”.
NOTE: It’s important that you name your bucket exactly as your domain. So if in my case, I created a bucket named www.stage-threads.com. - Leave all options as they are for the next step, Properties and click “Next”.
- In Step 2, Configure Options, uncheck the “Block all public access” option, check the box above to acknowledge that you will be allowing public access to the bucket, then click “Next”. Since it’s a website, we definitely need the public to be able to access it.
- Hit “Create Bucket”.
Properties Configuration
- Navigate to your new S3 bucket, and click on the “Properties” tab.
- Click on the “Static website hosting” card.
- Select the “Use this bucket to host a website” option.
- Enter index.html in the index document field and error.html into the error document field. Index.html Is the default page, just like a standard server setting. Error.html will be the 404 page. Pretty easy, right?
- Hit save.

Permissions Configuration
- Click on the “Permissions” tab.
- Click the “Access control list” button.
- Select “everyone” under the “public access” section.
- In the slide-out options, check the “read bucket permissions” under the “Access to this bucket’s ACL” section.
- Hit save.
- Click the “Bucket Policy” tab.
- Paste the following JSON code into the ARN editor and save. Change the “Resource” domain to your domain and hit Save.
{ "Version": "2008-10-17", "Id": "PolicyForPublicWebsiteContent", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::www.stage-threads.com/*" } ] }
.

Upload Files
- Click on the “Overview” tab.
- Drag and drop all your website files on the “Upload” button, then hit the “Upload”” button in the popup.
Check it


What About WordPress or Dynamic Websites?
To convert a dynamic website to a static one, you’ll essentially need to “download” the complete website. If you’re a Linux or Mac user, you can use wget with flags such as this:
`wget -r -l inf http://www.yourdomain.com`
This will download your entire website – pages, assets, all properly linked.
Windows users will need to find an alternative solution, such as httrack or something similar.
Create an Amazon S3 Bucket for the naked domain
Create Bucket
- Go to “Services” -> “S3” -> “Create bucket”.
- Enter your bucket name and region. NOTE: It’s important that you name your bucket exactly as your domain. So if in our case, we are creating a bucket for stage-threads.com.
- The next steps are identical to the first bucket we created. Uncheck the “Block all public access” option and check the box to acknowledge that you will be allowing public access to the bucket. Since it’s a website, we definitely need the public to be able to access it.
- Hit “Create Bucket”.
Properties Configuration
- Navigate to your new S3 bucket, and click on the “Properties” tab.
- Click on the “Static website hosting”.
- Select the “Redirect Request” option. NOTE: This is different from the previous bucket setup.
- Enter your www domain name in the “Target bucket or domain” field. In my case, it’s www.stage-threads.com.
- In the “Protocol” field, enter “https”.
- Hit save.

Permissions Configuration
- Click on the “Permissions” tab.
- Click the “Access control list” button.
- Select “everyone” under the “public access” section.
- In the slide-out options, check the “read bucket permissions” under the “Access to this bucket’s ACL” section.
- Hit save.
- Click the “Bucket Policy” tab.
- Paste the following JSON code into the ARN editor and save. Change the “Resource” domain to your domain. Notice how the “Resource” domain is different.
{ "Version": "2008-10-17", "Id": "PolicyForPublicWebsiteContent", "Statement": [ { "Sid": "PublicReadGetObject", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::stage-threads.com/*" } ] }

Step 2: Setting Up SSL for CloudFront
Now that we have the site running on the default AWS domain, we need to change this so that we can run it on our own domain. In my case, I will run the main site on www.stage-threads.com and set up a 301 redirect for stage-threads.com to redirect to www.
To accomplish this, we’re going to put CloudFront in front S3 for better performance. However, we’re first going to install the free AWS SSL certificates. This is a recent requirement by Amazon. If you’d like, you can read more about how AWS has made it mandatory that custom domain CloudFront distributions use https .
- one for the naked domain, in my case stage-threads.com,
- and a wildcard cert for all other subdomains, including www.
DNS: Read this before moving on...
Luckily, the move is very easy. Just follow this tutorial on how to migrate a domain from GoDaddy to AWS Route 53 .
IF YOU RUN INTO ANY ERRORS:
- Make sure to remove your SOA record from the text file. This conflicts with Route 53’s.
- Make sure to remove your NS records from the text file. Your name servers will now be on AWS.
AND YOU CAN ALWAYS REVERT…
If something doesn’t work out, you can always revert to GoDaddy’s name servers 🙂
Install an SSL certificate for the naked domain
- Go to “Services” -> “Certificate Manager” , then click the “Request a certificate” button.
- Ensure that “Request a public certificate” is selected, then click the “Request a certificate” button in the lower right corner.
- In the “Domain Name” field, enter your naked domain. In my case, I entered “stage-threads.com”.
- Select “DNS validation” then click “Next”, followed by “Review”, then “Confirm and request”.
- At this point, you should be at the “Validation” screen of the process. Since we’re using Route 53 for our DNS management, simply click “Create record in Route 53”, followed by “Create”, then “Continue”.
- You should now see your “Certificates” screen with the status for your new cert most likely in the “pending validation” status.
Create a wildcard AWS SSL Certificate for the www subdomain
- Click the “Request a certificate” button again to create a new cert.
- Ensure that “Request a public certificate” is selected, then click the “Request a certificate” button in the lower right corner.
- In the “Domain Name” field, enter your domain with an asterisk (*) as the subdomain. In my case, I entered *.stage-threads.com. <---This is different from the previous cert.
- Select “DNS validation” then click “Next”, followed by “Review”, then “Confirm and request”.
- At this point, you should be at the “Validation” screen of the process. Again, because we’re using Route 53, simply click “Create record in Route 53”, followed by “Create”, then “Continue”.
- You should now see your “Certificates” screen with the status for your new cert most likely in the “pending validation” status.
Step 3: Setting Up CloudFront Distributions
- One for the naked domain
- One for the www subdomain
Create a CloudFront Distribution for the naked domain
- Go to “Services” -> “CloudFront” to open up your AWS CloudFront panel.
- Click “Create Distribution” followed by “Get Started” under the Web delivery method section.
- In the “Origin Domain” field, select your S3 bucket, BUT… and this is important … you’ll need to change the S3 part of the domain to include your bucket domain INCLUDING the region . For my bucket, it’s www.stage-threads.com.s3-website-us-east-1.amazonaws.com. Here is an explanation why this is so.
- In the “Default Cache Behavior Settings” section, select “Redirect HTTP to HTTPS” for the “Viewer Protocol Policy” field.
- In the “Distribution Settings” section, type in your naked domain name into the “Alternate Domain Names (CNAMEs)” field. In my case, I typed in staged-threads.com.
- In the “SSL Certificate” section, select “Custom SSL Certificate”.
- Click on the text field below the selection and select the certificate for naked domain
- Click “Create Distribution”.
Create a CloudFront Distribution for the www domain
- Go to “Services” -> “CloudFront” to open up your AWS CloudFront panel.
- Click “Create Distribution” followed by “Get Started” under the Web delivery method section.
- In the “Origin Domain” field, select your S3 bucket for the www bucket. Again make sure that you use the website endpoint, which includes the region, not the API endpoint. More about this here.
- In the “Default Cache Behavior Settings” section, select “Redirect HTTP to HTTPS” for the “Viewer Protocol Policy” field.
- In the “Distribution Settings” section, type in you naked domain name into the “Alternate Domain Names (CNAMEs)” field. In my case, I typed in www.staged-threads.com.
- In the “SSL Certificate” section, select “Custom SSL Certificate”.
- Click on the text field below the selection and select the certificate for wildcard (*) version of the domain
- Click “Create Distribution”.
Step 4: Setting Up the DNS “A” Records
For the final step of this whole process, we’ll point the DNS “A” records to the CloudFront distributions. In our case, we will run the main site on www.stage-threads.com and set up a 301 redirect for stage-threads.com to www.
Set up A record for www
- Go to your AWS Route 53 panel and click on “Hosted Zones”.
- Select your hosted zone for your domain.
- If you already have an “A” record for the naked domain and/or a www “A” or CNAME, delete them by selecting them and choosing Delete from the Actions menu.
- Click the “Create Record Set” button.
- In the “name” field, enter www.
- In the “Type” field, select A-ipv4 Address.
- Select “yes” for “Alias”.
- Click on the “Alias Target” field and under the “– CloudFront Distributions –” section, select your www distribution, then hit “Create”.
Set up A record for naked domain (non-www)
- In the AWS Route 53 control panel, select your hosted zone.
- Click the “Create Record Set” button.
- In the “name” field, do not enter anything.
- In the “Type” field, select A-ipv4 Address.
- Select “yes” for “Alias”.
- Click on the “Alias Target” field and under the “– CloudFront Distributions –” section, select your naked domain distribution for the and hit “Create”.
https://stage-threads.com should redirect to https://www.stage-threads.com
http://stage-threads.com should redirect to https://www.stage-threads.com
http://www.stage-threads.com should redirect to https://www.stage-threads.com

Website File Updates & Deletions
CloudFront Invalidation
- Go to the AWS CloudFront distributions panel and click on your www distribution id from the list. We only need to invalidate the www version.
- Click on the “Invalidations Tab” , then click the “Create Invalidation” button.
- In the “Object Paths” field, enter the files you want to to invalidate/refresh – one file per line. You can use the asterisk (*) as a wild card.
- For example,
- Index.html invalidates your home page only
- images/* invalidates everything in the images directory
- * invalidates all the files – the whole website
Dynamic Website Functionality
Embeddable Forms
- You can offload all maintenance of the form processing and storage to a 3rd party
- The data never hits your server so you don’t have to worry about sensitive information storage.
Media
Conclusion
https://ithoughthecamewithyou.com/post/enable-gzip-compression-for-amazon-s3-hosted-website-in-cloudfront
https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-validate-dns.html
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html
https://aws.amazon.com/about-aws/whats-new/2019/04/amazon-cloudfront-enhances-the-security-for-adding-alternate-domain-names-to-a-distribution/
https://aws.amazon.com/premiumsupport/knowledge-center/s3-website-cloudfront-error-403/
https://lobster1234.github.io/2017/05/10/migrating-a-domain-to-amazon-route53/
https://hostingtribunal.com/blog/how-speed-affects-website/#gref
Contact Us
We'd be happy to hear from you. Contact us via email, phone or online.
We are located in Northwest Indiana, just minutes from Chicago. We work with small business locally but we also work with entities across the United States.
Snail Mail: 1745 Sheridan Ave, Whiting IN 46394
Email: info@elegrit.com
Phone: (219) 801-6745