API Gateway

Background

This repository contains cloudformation template to deploy a serverless API service which will receive and store data about sports teams into a NoSQL database.

The Cloudformation stack mainly deploys the following AWS resources:

Service Description
API Gateway Handles the http traffic
IAM Role to be used by Lambda Function
Lambda Function Extract data from the http request and update the database
Lambda Function Receives data from the DynamoDB stream and publish to SNS topic
DynamoDB Table NoSQL Database
SNS Topic Users subscribed to this topic receive alerts when a new item is added to DynamoDB table

Prerequisites

The following tools are required to run this cfn template

Linux/MacOS

pip install awscli
  • AWS profile configured (or) AWS instance with proper instance profile assigned

example:

aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: ap-southeast-2
Default output format [None]: json

The IAM user/role being used must have sufficient permissions to create AWS resources listed in the Background section.

Usage

Parameters

Cloudformation template takes the following parameters:

  • MyName - Name of the Candidate running this test which will be appended to AWS resource names.
  • Email - Optional email address that will receive alerts.
  • HttpEndpoint - Optional HTTP endpoint that will receive alerts via POST requests.
  • HttpsEndpoint - Optional HTTPS endpoint that will receive alerts via POST requests.
  • FallbackEmail - Optional email address that will receive alerts if alerts can not be delivered.

How to run

Clone the repo

git clone https://github.com/apsnaidu/contino-test.git

Deploy cloudformation using aws-cli:

cd contino-test
aws cloudformation deploy --template CfnTest.yaml --stack-name cfnstack --parameter-overrides MyName=yourname Email=youremail@company.com --profile default --capabilities CAPABILITY_IAM

Test

Once the cloudformation stack is successfully deployed you should have the API gateway endpoint published as one of the Outputs with the name RootUrl in AWS cloudformation console.

You can also retrive the value using aws-cli

aws cloudformation --region ap-southeast-2 describe-stacks --stack-name cfnstack --query "Stacks[0].Outputs[?OutputKey=='RootUrl'].OutputValue" --output text --profile default

Make sure you subscribe to the SNS topic by clicking on the Confirm subscription link in the email you would've received from AWS with subject AWS Notification - Subscription Confirmation

API can be tested using Postman collection available in the repo under postman directory by replacing the RootUrl environment variable with the corresponding value generated by your cloudformation template

Alternatively you can use curl to test the API endpoint as below:

example on linux/Mac OS

curl --header "Content-Type: application/json" --request POST --data '{"team_country": "Australia", "team_name": "Contino", "team_desc": "DevOps", "team_rating": "A+"}' https://f2j0zck5a2.execute-api.ap-southeast-2.amazonaws.com/v1/add_new

on Windows (assuming curl for windows https://curl.haxx.se/windows/ is installed)

curl -X POST -H "Content-Type: application/json" -d "{\"team_country\": \"Australia\", \"team_name\": \"Contino\", \"team_desc\": \"DevOps\", \"team_rating\": \"A+\"}" https://f2j0zck5a2.execute-api.ap-southeast-2.amazonaws.com/v1/add_new

If everything is successful, you should receive an email notification from AWS with the subject A new item has been added to table <tablename> and item content as message body when ever you add a new item to the DynamoDB table using API Gateway endpoint.

If not, you can check for any errors under cloudwatch log groups with names starting with /aws/lambda/teststack-SNSLambdaFunction and /aws/lambda/teststack-LambdaFunction where teststack is the name of the cfn stack.

Cleanup

Do not forget to delete the resources created using AWS console or CLI once the testing is finished.

aws cloudformation delete-stack --stack-name cfnstack --profile default

Recommendations:

  • API Gateway endpoint is currently public which means anyone with the API endpoint will be able to POST which is not desirable. Implement the below to make it more secure

    • Secure API method with an API key

    • Implement a custom Authorizer using lambda or Cognito User Pool.

  • Encryption in transit can be enabled for Lambda environment variables if required using custom KMS keys.

  • Point-in-time recovery can be enabled for DynamoDB table as a backup option (which incur additional charges)

  • Lambda execution role permissions can be made more restrictive by specifying required resources in place of using wildcards in Resource definitions.