Multi-region Serverless Application with simulated Regional Fail-over and Routing using Amazon API Gateway and Lambda
Tags: aws, serverless, cloud
Published: 2022-02-04 17:54:33

In this post (and associated Youtube playlist), we will create a Serverless application, deploy it to two different AWS regions and use Route53’s latency based routing to drive traffic to a regional end point. We will use Route53’s healthcheck feature to achieve active-active setup which can fail over between regions.

## Issue
When you deploy a Serverless application, the default API endpoint type is edge-optimized, which enables clients to access the API through Amazon Cloudfront distribution. For globally diverse clients, it improves the connection time. But there is one problem. For CDN, the custom domain name is globally unique and In case of Lambda integration, the Lambda is only deployed in Single Region. Therefore, we can not use "edge optimized" to achieve active-active failover setup with Route53.

## Solution
To solve this problem and demo the solution, we will deploy the Serverless application in 2 different regions and choose API end point type as “Regional“. The custom domains that we get are now regionally unique. In the Serverless application, we will expose an end point that’s just for performing health-check. For the API, in Route53, we will setup Latency Based Routing, which directs the users to closest / best region based on latency. We will also setup health check in Route53. To mimic the regional failover, we will make the healthcheck end point FAIL, and Route53 should start directing the traffic to the other region.

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

As shown in the architecture diagram above, the clients requests are getting routed to Region A (solid box). When the health check starts failing, the Route53 will start to direct the traffic to Region B, until the HealthCheck starts passing again on Region A.

## Tasks
(Some of the following are NOT FREE Tier applicable)

1. Purchase a domain / or you can use an already purchased domain. I have an old domain in godaddy, which I will use for this.
2. Go to AWS Console > Route53 and Create a new HostedZone, with the domain name you are planning to use.
3. We need to set the nameservers on the domain (in case you have the domain registered through a 3rd party like GoDaddy)
4. The step 3 may take a few mins to 24 hours.
5. Let’s create Simple Serverless application with 2 end points and 2 lambdas. First being the /hello and another one /health. Important to keep the endpoint type as “Regional“. Just to keep the demo simple, for the HealthCheck setup in Route53, we will look for a specific string in the response from /health end point. In practical usecase, you would be checking status of one or more of your critical components and determine if the application is healthy or not. (Sample code is in the github)
6. We will deploy this application to “us-west-2” (Closest to me) and “us-east-1” regions.
7. Let’s try to access both the end points in both the regions and make sure we are getting expected response.

I am using serverless framework as IaC and NodeJS for this solution:

Serverless.yml

```
service: multiregion-failover
frameworkVersion: '2'
provider:
  name: aws
  runtime: nodejs12.x
  lambdaHashingVersion: 20201221
  endpointType: REGIONAL
functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: /hello
          method: get
  health:
    handler: handler.health
    events:
      - http:
          path: /health 
          method: get 
```

Lambda Function
```
'use strict';

module.exports.hello = async (event, context) => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'Hello from the function in region: ' + context.invokedFunctionArn.split(':')[3]
      },
      null,
      2
    ),
  };
};

// We will check for string HEALTHY when we setup the Healthcheck in Route53. In production environment, the HealthCheck is based // on checking multiple critical components of your application
module.exports.health = async (event, context) => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'Healthy instance! HEALTHY from region:' + context.invokedFunctionArn.split(':')[3],
      },
      null,
      2
    ),
  };
};
```

Solution Code: https://github.com/mycloudtutorials/serverless-demos/tree/master/serverless-multiregion-failover-demo


All the Tasks performed are in the following youtube playlist. 
The entire playlist (all 8 videos) can be accessed at
https://youtube.com/playlist?list=PLss_bBhYYErsTc24oZSDUUO3PXLmMh9KU