How to build a Serverless and cost-effective failover solution using a backup website with traffic monitoring! (part 1/2)
Tags: awscloudfrontdistribution, staticwebsitehostings3, awslambda, serverlesswebsite
Published: 2023-08-15 13:23:30




Building and maintaining a website or a web app would take time and effort during the development phase or due to a major issue that could cause a downtime that require some time to resolve it.

We often design and configure our system to reduce or eliminate incidents that could cause a sever impact, by setting up backups and Disaster Recovery setup (Warm Standby or Active/Active) depending on the RPO/RTO requirements and cost implications. Along with this, especially during the development or pre-production stages in the cloud, we could build a serverless cost-effective failover solution to a backup website and monitor traffic.

During the [AWS Cloud Bootcamp](https://github.com/astroveny/aws-bootcamp-cruddur-2023) by [Andrew Brown](https://www.linkedin.com/in/andrew-wc-brown/) [(ExamPro)](https://www.exampro.co/), we built a **Cruddur** web app, so I had to design and deploy a _failover solution_. In this example, the web app runs on **ECS Fargate** behind an **ALB Load Balancer** which is registered on **Route 53** hosted zone. The failover solution consist of setting up a **S3** static website as an origin to a **CloudFront** distribution, and registered on **Route 53** hosted zone. We will enable **Route 53** *failover routing policy* so that traffic is routed to the static website in the event that web app is unavailable. 

The benefits of **CloudFront** would be to cache the content globally and utilize HTTPS using TLS which encrypt data in transit. To start, we first need to set up an **S3** static website, after which we will create a **CloudFront** distribution with the **S3** static website as the origin. Next, we will Update the **Route 53** hosted zone, edit the primary A record to enable failover by evaluating target health, create a new A record with the same record name to point to the **CloudFront** Distribution domain name, and route as secondary failover.

Finally, we will monitor the web traffic by enabling CloudFront logging to a new **S3** bucket and reduce the log file count by invoking a **lambda** function once a new log file is created. Lastly, we will query the logs using **AWS Athena**. 

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

---  
### Create S3 Static Website Bucket

- Go to AWS S3 console
- Create a bucket using DomainName as the name of the bucket
- Select the bucket then Edit **Static website hosting** under **Properties** tab
- Select **Enable** Static website hosting
- Enter the **Index document** file name e.g. index.html that display "Under Maintenance"  
- Save changes 
  
---  

### Upload Static Website Files

We will upload the content of the static website. This can be a simple single-page website which only requires uploading the html and css files or more complicated website built using for example JavaScript, which requires npm build of the website files then upload the build files.

In both ways, we may follow the following steps.

- Go To AWS S3 Console
- Select the bucket name created previously 
- Click on **Upload**
- Add the files of the static website  
- Select **Upload**  
  
---  
### Cloudfront Distribution 

We will use the existing ACM certificate which is already used by the ALB.

- Go to AWS CloudFront console
- Click on **Create Distribution**
- **Origin domain:** Select the S3 bucket created previously 
- Click on **Use website endpoint**
- **Viewer/Viewer protocol policy:** Redirect HTTP to HTTPS
  - **Allowed HTTP methods:** GET, HEAD
- **Settings/Alternate domain name (CNAME):** Add your DomainName
  - **Custom SSL certificate - optional:** Select your ACM certificate
  - **Supported HTTP versions:** Select both HTTTP 2/3
- Click on **Create distribution**  

---  
### Update S3 Bucket Policy

- Go to AWS S3 console
- Select **Permissions** tab, Edit **Bucket policy** 
- Add the following policy (replace the "S3-Bucket-ARN" & "cloudfront-ARN" with the respective value)
```json
{
        "Version": "2008-10-17",
        "Id": "PolicyForCloudFrontPrivateContent",
        "Statement": [
            {
                "Sid": "AllowCloudFrontServicePrincipal",
                "Effect": "Allow",
                "Principal": {
                    "Service": "cloudfront.amazonaws.com"
                },
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::S3-Bucket-ARN/*",
                "Condition": {
                    "StringEquals": {
                      "AWS:SourceArn": "arn:aws:cloudfront-ARN"
                    }
                }
            }
        ]
      }
```  
---  
### Route 53 Hosted Zone Records

Enable primary failover routing policy for the exiting A record pointing to the web app, then create a new A record that will point to the CloudFront distribution URL "Static website" and enable secondary failover routing policy.

- Go to AWS Route 53 console
- Edit the exiting primary A record pointing to your website via the ALB
- Change **Routing policy:** to Failover
- **Failover record type:** Primary
- Make sure **Evaluate target health** is enabled
- **Record ID:** enter any value
- Click on **Save**
- Create a new A record to point to the static website:
  - Select **Create record**
  - Select **Record type** as A record
  - Enable **Alias** then under **Route traffic to** select CloudFront distribution
  - Select the CloudFront Distribution domain name created in the previous step  
  - Select **Routing policy** as Failover
  - Select **Failover record type** as Secondary 
  - **Record ID:** enter any value
  - Click on **Create record**

Route 53 can now failover to the **static website** in the event that the web app is unavailable due to maintenance.

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

---   
In this phase we have completed deploying an **S3** static website as an origin to the **CloudFront** distribution, then updated the **Route 53** configuration to add a new A record pointing to the static website and enabled failover routing policy.

[In the next phase (part 2/2)](https://dev.to/astroveny/serverless-and-cost-effective-failover-solution-using-backup-website-with-traffic-monitoring-part-22-46ff) we will continue deploying serverless services to enable traffic monitoring using S3 bucket to save the **CloudFront** access logs, create a **Lambda** function to reduce the log count and use **Athena** to query the access logs data.