Static Website Hosting with Amazon S3, CloudFront and CloudWatch metrics in 5 minutes or less
Tags: aws, cloud, s3
Published: 2023-09-24 21:18:08


![Architecture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yq53r8e22v2i3pt9ihak.png)
The AWS cloud platform provides an all-in-one managed solution ideal for hosting quick, secure, and reliable static and even dynamic websites. We’re going to use Amazon Simple Storage Service (S3), Amazon’s CDN service- CloudFront and their monitoring service-CloudWatch to deploy and serve a website. But first, an introduction.

## What is Amazon S3?
Amazon S3(Simple Storage Service) is an object storage service that allows you to store unlimited objects and connect virtually all services to your bucket to serve, store and retrieve content over the internet. S3 provides a managed and scalable object storage solution for all data types from files to multimedia content and for this case, static website hosting.

## What is CloudFront?
CloudFront is an AWS Content Delivery Network (CDN) service that lets users serve content globally with low latency, high transfer speeds and secure connection. CloudFront leverages AWS Edge Locations as part of the global infrastructure to cache and deliver content closer to users across the world so they can experience millisecond latency and smooth performance. also provided by AWS, it enables users to deliver content globally with low latency, high data transfer speed, and securely delivered. With CloudFront, you also enjoy SSL/TLS encryption for your website with the option to push metrics to CloudWatch for even finer control and monitoring of your environments.

## The Plan

1. S3 will store static website files and media content.
2. A CloudFront distribution will serve the website to users across the world-the website is served through edge locations but the files are held in S3.
3. CloudWatch will provide a dashboard to monitor the website.

## Host the static website on S3
There are tons of website templates online. You can find a template from [bootstrapmade.com ](https://bootstrapmade.com/)and customize it to your style needs. If you have a website already, that’s even better.

## Create the S3 bucket
We will provision an S3 bucket that will store the website content including the HTML and CSS files and also the media files. 

- Go to S3 console and choose create bucket. 
- Click ‘Create Bucket’. Choose a globally unique bucket name and AWS region.
- Follow the prompts to create your S3 bucket.
- Untick “Block all public access” and acknowledge the change.

---

 Since we want our static website accessible from the internet.
For now, we will enable public access but this is a security concern but we’ll fix it in a few.

---

- That’s it, you don’t need anything else in this menu and can click ‘Create bucket’.

- Once the bucket is created, click on its description to open it then choose Upload and upload all the website files. 

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

- Once the files are uploaded, go to the bucket homepage, go to properties tab and scroll down to find the “Static website hosting” section and enable it.
- Choose "Host a static website".
- Choose an Index document and an Error document. You can fill in “index.html” into both.

![Hosted website](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z642zzi4md48l6hl1czj.png)
- Since this bucket will be used to host a website, ensure to make you index.html document as the index document part. 
- Change any additional settings you want then click Save.

---
Note down endpoint URLs displayed for the bucket in the “Static website hosting” properties panel. (Endpoint URLs look like http://yourbucketname.s3-website-us-east-1.amazonaws.com.)
If you try to open the endpoint URL in your browser, you might get an access denied error, let’s fix that by editing the S3 Bucket Policies.

---

![S3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8zrpdwlrej379wlr10qv.png)
- In the S3 bucket you just created, go over to Permissions. Then Bucket Policy.
You need a bucket policy that will allow public website hosted on it. You can use the official AWS policy generator for these purposes, which can be found at: AWS Policy Generator
If you choose to use the generator, choose S3 bucket policy as the Type of Policy. Principal will be “*” (without quotes), and Actions will be `GetObject`.
The * here is a wildcard that means access for all requesters. The policy looks like:

```
{
 "Version": "2012-10-17",
 "Statement": [
  {
   "Sid": "PublicReadGetObject",
   "Effect": "Allow",
   "Principal": "*",
   "Action": [
    "s3:GetObject"
   ],
   "Resource": [
    "arn:aws:s3:::<BUCKET_NAME>/*"
   ]
  }
 ]
}
```
To find your ARN or Amazon Resource Name, scroll to the top of the window and you can find it written as
  `arn:aws:s3:::<bucket_name>.`


![ARN](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d6z67xyfupyc6qb0fg5r.png)
Save to accept the changes and that’s all you need with S3 for now.

---
If the website works just by hosting on S3, why then do you need CloudFront?  “Well, if you reload the endpoint link on your browser, your website has a 'Not Secure' tag. This is a red flag which means that your website is hosted but not secure. CloudFront allows you to serve your website and it’s contents securely.”

## Configure CloudFront CDN
We’ll create a CloudFront CDN distribution linked to the S3 bucket so that anyone who accesses the distribution will be viewing the S3 bucket hosted static website securely, with millisecond latency.

## Create CloudFront distribution

- On the AWS Console search for and open CloudFront.
- Click Create Distribution.
- Under Origin, for Origin domain, choose the Amazon S3 bucket that you created previously. It should be part of the selection menu.
- You should see an Origin settings page with many options and fields.

![Origin section](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u4k9nxpjhx4mdjmy8ove.png)

For the Origin Domain Name, you will need to paste the S3 endpoint URL from earlier. If you don’t have it, open the S3 console in another window, click on your bucket name, then click on Properties and scroll down to Static website hosting. Copy over the highlighted part of the Endpoint URL:

- Skip the next parts because they involve a domain name and certificates. 
- For Bucket policy, select Yes, update the bucket policy.
- For the settings under Default Cache Behavior Settings, under Viewer, set Viewer protocol policy to Redirect HTTP to HTTPS and accept the default values for the rest.

---

If you’d like to know more about cache behavior options, see Cache behavior settings in the Amazon CloudFront developer guide.

---

In the Web Application Firewall (WAF) section you can choose to either enable or disable AWS WAF security protections. This is a paid service and you can quickly rack up costs outside the free tier limits.
If you have an SSL certificate, you can add it under the Custom SSL Certificate for CloudFront SSL encryption setting. 
Click Create Distribution at the very bottom of the page.
Provisioning the Distribution takes 10-20 minutes. Once it is provisioned (Status = Deployed, State = Enabled), you can test it by pasting the URL under Domain Name into your browser. You should see the website you uploaded into S3.

---
Now if you recall, you still have public access enabled on the S3 bucket, time to fix that. The CloudFront distribution setup should have given you a prompt to change the S3 bucket policy, copy the policy then go to the s3 bucket hosting the website and, in the permissions tab, choose edit button for the bucket policy section and paste the new policy.

```
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::week20bucket/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudfront::035431961317:distribution/E240YKEWLBC6VJ"
                }
            }
        }
    ]
}
```
 
You might geta JSON syntax error, which is easy to fix; remove the old policy and it should all be good. If the error persists, choose confirm changes to get a link to a JSON syntax formatter.
Now go back to the CloudFront distribution and find the distribution link and open it on another browser window, it should now work. You should be able to view your website and its contents with a CloudFront URL that has a secure tag.

## Set up CloudWatch Metrics for CloudFront

- On the CloudWatch window, click on Alarms then create alarm
- Click on Select Metric and type the name of the metric into the search box.
- Choose the metric for the service you’re going to monitor (under CloudFront > Per-Distribution Metrics)
- Click Select Metric.

![CloudWatch metrics](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kvb7f3jsg1ey5sejq391.png)
- Configure your thresholds.
The Requests metric measures the number of requests made to your distribution. Major changes in this metric can signal issues in your application, such as errors in clients calling the distribution.
The BytesDownloaded metric measures the number of bytes downloaded from your distribution.
xxErrorRate is the percentage of responses in the 4xx range. A spike in this metric could suggest a changed API or moved resource resulting in bad requests or auth issues. Set this to 10% average limit.
5xxErrorRate measures the percentage of responses in the 5xx range. If your distribution is backed by servers and this metric spike, you likely have issues affecting your servers’ ability to respond to requests. Set this to 10% average limit.
- Click on Additional Settings to choose how many datapoints to alarm on and what to do when data is missing (we recommend ignoring missing data and just keeping the previous state to keep alerts from flapping)
- Click Create Alarm.
Unfortunately, since CloudWatch only supports creating an alarm on a single metric, you’ll have to repeat the whole process for each service and metric combination. This can get incredibly time consuming and tedious.

---

And that’s it. You should now have a dashboard that shows all the relevant and custom metrics for your website. You can try reloading the website to see how the metrics dashboard changes.
You have just deployed a website on S3 and made it available globally through CloudFront CDN.