How to upload a static website on Amazon (AWS) S3 + CloudFront + CertificateManager
If you didn't know already, you can host a static website on AWS S3. I will try to explain all the details you need to upload a static website on S3 and put CloudFront in front of this to load the website even faster.
Advantages
- It’s a lot cheaper. You will pay for the size of the files that you store on S3 (a few cents) and for the traffic (bandwidth) to the internet (this depends on the load you have on your website)
- It’s a lot faster for users. AWS S3 it’s a lot faster than most share hosting available and if you add CloudFront in front of S3, which is a CDN (Content Delivery Network) you are guaranteed to have the fastest website (if your code is optimized).
Let’s get started
First, you need to open an Amazon Web Services account, add a credit card and all the info needed (you will be charged at the end of each month if it’s something to charge, but the credit card is mandatory). You have 12 months a lot of free services including S3 and others so probably in the first year you will not pay anything (if it’s not extra heavy load). Go here to open an account: https://portal.aws.amazon.com/billing/signup
Step by step for AWS S3
S3 = Simple Storage Service. So we will use S3 to host our files on Amazon infrastructure. S3 also has a nice feature to make a bucket as Static website hosting and this feature we will use here. Below are the exact steps that you need to make.
- Go to S3 service: https://s3.console.aws.amazon.com/s3/home
- Create a new bucket and name it exactly like your domain including www and the TLD. For Region choose one that is close to your customers. It should be like in the example:
- Click Next, Next to Finish to create the bucket.
- After the bucket is created click on it and go to Properties -> Static website hosting, choose the option Use this bucket to host a website and add index.html for both Index and Error document (if your index file is different this should be changed to that filename). This means that index.html file will be called by default if no file is specified and also if there is an error like the wrong path. It should look like this:
- Next, go to Permissions -> Bucket Policy and add something like this, but change with your bucket name (the domain).
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::www.your-domain.com/*"
}
]
}
- Now select from Permissions -> Block public access and edit it so only first 2 are selected and leave the last 2 unselected like in this image and Save
- Now let’s add our website files to S3. Go to Overview and click Upload. Add all your files and directories directly in the root of the bucket. In the root, you should have the file called index.html (or how you defined in Index Document before).
- At this point it should work as a static website, but not yet with CloudFront nor with your custom domain. Let’s check if everything is working ok until now before going further. Go again to Properties -> Static website hosting and at the top of that box you will see Endpoint and a link. Click on it, it should load your website. If you have an error check again the steps until now or leave me a message.
- [Not Recommended] If you don’t want SSL certificate and CloudFront Distribution in front of this you can simply go and point a CNAME to this endpoint, but I dont’ recommend this way so better follow next steps too.
Step by step for AWS Certificate Manager [SSL]
Because we will use a custom domain and because we want to have https (SSL) we need to create an SSL certificate for this domain. It’s free and managed by Amazon so we don’t need to do anything after creating it. In order to create it follow the steps:
- Go to Services -> Certificate Manager
- Click the blue-button Request a certificate and select Request a public certificate
- For Domain name add your custom domain both with www and not www and click Next
- Choose DNS validation because it’s easier and you only have to add some entry in DNS to verify that you have that domain and click Review
- Confirm and request and will show you what records you have to add to your DNS in order to validate the domain. You will need to add a CNAME record for each domain (with and without www). If you have your DNS set on Route 53 it’s a bit easier, just click the blue button Create record in Route 53 and Create. If it’s somewhere else just go there and add the records. This usually takes a few minutes to propagate to the internet, after this you will see the certificate with green status Issued like this:
Step by step for AWS CloudFront
This step is optional, but it’s recommended. CloudFront is a fast content delivery network (CDN). I recommend using CloudFront because the resources of your website will load faster this way. If it’s not so important for you this, you can skip this part. This will add extra money to the bill, depends on the traffic that you have to your website and how many GB are downloaded. Usually, it’s still very cheap and it’s better to implement this step too and also first year it’s free 50GB traffic OUT. So let’s get started:
- Go to Services -> CloudFront and click the blue button Create Distribution
- Select Web and Get Started and now you will need to configure. All the settings that I don’t specify here can remain as default setting.
- Origin Domain Name -> select your S3 bucket
- Origin Path -> leave empty
- Restrict Bucket Access -> Yes
- Origin Access Identity -> Create a New Identity and Comment can be leaved as default.
- Grant Read Permissions on Bucket -> Yes, Update Bucket Policy
- Viewer Protocol Policy -> I recommend to go with Redirect HTTP to HTTPS so all the traffic will be redirected to HTTPS.
- Allowed HTTP Methods -> GET, HEAD
- Price Class -> I recommend to use All because it’s the best performance, but if you want to be cheaper it’s ok to select something else.
- Alternate Domain Names (CNAMEs) -> Add here your domain name like www.your-domain.com (change with what domain you use).
- SSL Certificate -> Custom SSL Certificate and select your domain from the list.
- Default Root Object -> index.html — the same filename as set in S3 as Index Document
- Finally, click the blue button Create Distribution to create this CloudFront distribution
- The status will be In Progress for a while and after that will change to Deployed. At this point, the distribution should be deployed and now you should be able to see the website if you go to the CloudFront distribution URL that you can find in General -> Domain Name and it looks like this: d12345abcdef.cloudfront.net.
- If all is working ok go to your DNS Manager (Route 53 if it’s on AWS) and add a CNAME from www to the URL of CloudFront distribution, in a few minutes it should propagate and should work ok.
Redirect non-www traffic to www
If you are using Route 53 the solution for this is:
- Create a new S3 bucket with the domain name without www and the exact same setting as the other one (When creating choose Copy settings from an existing bucket and select the other bucket).
- Go to Properties -> Static website hosting and now choose the option Redirect requests and add the domain with www and protocol https (recommended).
- Go to Route 53 and add a new record in your zone
If you are using another platform for DNS you should check that platform, many have a redirect option from one URL to another.