AWS Dev and Deploy Series: API Gateway Integration with Application Load Balancer
By: Sriharsha Polimetla
Tags: Rest Api, Load Balancing, DevOps, Api Gateway, AWS

Photo by Gabriele Stravinskaite on Unsplash

This is a part of the series to demonstrate deployment of a (Production Ready) Springboot Application with PostgreSQL Database on AWS Fargate using CI/CD tools of AWS.

This is the third in the series. Please read part1 and part2 if you would like to follow the overall application.

So far till Part2, I have developed a basic Springboot Application and deployed it in a CI/CD way. This Application reads and writes to a RDS instance. With this implementation, the API is accessed using the Public DNS name of the ELB which routes the traffic to ECS instances. The ELB has no security definition on it and all requests are passed on to the container instances.

Why API Gateway?

API Gateway is a managed solution from AWS which can be used to create, publish and secure APIs at scale with low cost.

Some features:

Authentication for API access can be enabled at API Gateway level which serves as the front door for the applications, using an API Key and/or using a Lambda function. API requests can be limited per a fixed time frame to protect applications from brute force attack. Easy integration with swagger which makes API documentation easier. Lower Latency when integrated with Amazon CloudFront. API requests can be filtered out at the API Gateway if they do not have certain requirements. These requests will not reach the Application, thus failing fast.

Implementation

The code is found on my GitHub. The relevant branch for this is 3-elb-api-gateway.

Just as in part2 the custom domain is used for the API endpoint creation. This is much more user friendly than the random endpoint created by API gateway.

The Application Deployment and access flow looks as follows,

Application work flow with ELB and API Gateway

The file api-config.yaml is used to create the underlying resources for a API deployment such as Domain Name, SSL Certificate, API Key and a Usage Plan. Domain Name and SSL Certificate are optional if you do not own a domain name. You can still use API Gateway but with a randomly created endpoint.

API-config is a generic stack and the same can be used to deploy multiple APIs under the same domain name. The Usage Plan is specified with specific quota and Throttle limits to protect the API from Brute Force Attack. The values which I chose here are purely arbitrary and these values in a real scenario will be chosen upon API usage and necessity.

ApiUsagePlan:

Type: AWS::ApiGateway::UsagePlan

Properties:

Quota:

Limit: !Ref QuotaLimit

Period: !Ref QuotaPeriod

Throttle:

BurstLimit: !Ref ThrottleBurstLimit

RateLimit: !Ref ThrottleRateLimit

UsagePlanName: !Ref UsagePlanName

Although the same can be achieved without using swagger, I chose Swagger to separate API creation and definition. Using a swagger file also has a specific advantage of not having to create API documentation separately. This is out of scope for this post but a “good to know” point.

Swagger definitions are used to define the API Request and Response. This, in conjunction with the “Request Validator” is particularly useful in case of POST requests where there is a possibility of “Bad Request” coming in. Such requests are filtered out without reaching the Application Layer. The relevant section is as follows.

... x-amazon-apigateway-request-validators:

RequestValidator:

validateRequestBody: true # Checks JSON schema for POST requests

validateRequestParameters: true

x-amazon-apigateway-request-validator: RequestValidator .... definitions:

Employee:

type: “object”

description: “A Single employee entry”

properties:

employeeId:

type: integer

firstName:

type: string

lastName:

type: string

age:

type: integer

gender:

type: string

enum:

- MALE

- FEMALE

- OTHER

- “0”

- “1”

- “2”

required:

- firstName

- lastName

- age

Any incoming requests without the required fields or with an invalid type will be halted at API Gateway and a failure is notified to the API consumer.

The following is the relevant part for the Load Balancer and API Gateway Integration.

EmployeeApiStage:

Type: AWS::ApiGateway::Stage

Properties:

DeploymentId: !Ref EmployeeApiDeployment

RestApiId: !Ref EmployeeApi

StageName: !Ref Stage

Variables:

employeeELB: !GetAtt LoadBalancer.DNSName

DNS Name of the Load Balancer is used as a Stage Variable for the API deployed. This stage variable is used in the swagger file as shown below.

Summary

The Application is now CI/CD with every commit happening on GitHub to automatically build and deploy till Dev and wait for Approval for Prod and then automated again. There is also the usage of RDS instances which is a persistent and highly available DataBase solution. Although there is room for advanced protection such as Incognito Pools and Lambda Authorizers, this implementation offers enough firsthand protection for the API behind.

Until I come up with another idea: Clap on, Comment, Share and Follow!

Happy Coding!

👋 Join FAUN today and receive similar stories each week in your inbox! ️ Get your weekly dose of the must-read tech stories, news, and tutorials.

Follow us on Twitter 🐦 and Facebook 👥 and Instagram 📷 and join our Facebook and Linkedin Groups 💬