We know s3 can be used as media / object storage. But S3 can be used to serve static websites.
Evolution of 4 — tier server architecture and micro services led to decouple front end from back-end. Usually micro services are containerized using Docker, Kubernetes and other technologies. It is not a good decision to serve the static front end files using dockers since there is no much processing is done than just serving files.
First create S3 bucket with the same name of domain. Say your domain name is www.xyz.com then create bucket with same name.
Note :- The bucket name should be same as your domain name for some reasons.
Click on create to create the bucket. Then navigate inside bucket and click on properties. Select Static website hosting and check Use this bucket to host a website and save.
Then go to permissions tab > public access settings > Edit
Uncheck all the permissions and save.
Then click on Access control list > Everyone in Public access. Check Read bucket permissions and save.
Go to Bucket Policy and Enter the following snippet and save
Note :- Change the Resource to your ARN which will be displayed above the text box. Also don’t forget to add /* at end or ARN
Next we should obtain a SSL certificate to make it serve in https
We can obtain free SSL certificate using Lets Encrypt. To obtain the certificate install docker.
Note :- If you want to get certificate from AWS skip this step. and get your certificate from AWS certificate manager. You can follow this article https://medium.com/@itsmattburgess/hosting-a-https-website-using-aws-s3-and-cloudfront-ee6521df03b9
Run the docker service and run this command to obtain certificate.
docker run -it -v /path/to/your/directory:/etc/letsencrypt certbot/certbot certonly — manual — preferred-challenges dns — email firstname.lastname@example.org — server https://acme-v02.api.letsencrypt.org/directory — agree-tos -d ‘*.xyz.com’
Note :- Change path/to/your/directory to the directory you require. Certificates will be stored in that directory. Also replace email@example.com to your email id. You have to renew your certificate every 3 months.
After running this command it asks to add TXTrecord to your DNS before pressing enter.
Go to your Domain provider to add DNS TXT records.
Add a TXT record with the name and value displayed in the terminal.
Wait for few minutes before TXT record propagates through DNS then click enter in terminal to confirm that TXT record has been added.
If everything is successful then you will get success message and certificates will be stored in path/to/directory/live/xyz.com/
You can see few files with pem extension.
Next we need to upload these certificates to AWS CloudFront.
Go to AWS Certificate Manager > Import a certificate
Add the content of cert.pem to Certificate body
Add the content of privkey.pem to Certificate private key
Add the content of chain.pem to Certificate chain
Click on review and import if everything is successful then you can see certificate related to *.xyz.com
Then go to AWS CloudFront and select Create distribution > Get started under web.
In S3 bucket under static hosting you can see a url like this
Copy the address and paste in Origin Domain Name.
Select required Viewer Protocol policy and other required field.
In Distribution Settings add alternate domain names as www.xyz.com
Then in SSL Certificate select Custom SSL certificate and in drop down select the SSL certificate you uploaded in previous steps. Then click on Import certificate.
Then click on create distribution.
You can see Distribution status as in progress which might take 20–30 minutes.
Now copy the Domain name that is displayed in row and add that as CNAME record in your DNS panel.
You are done with the setup now go to your S3 bucket and upload your static files.
You can visit your s3 website link that is shown in static hosting to verify everything is working.
Once the distribution deployment gets successful you can visit your website https://www.xyz.com
If you get 403 error then you did something wrong while setting S3 bucket permissions.
If you get 404 error then you might not uploaded index.html or the file is missing.