Building a demo application and deploying it in AWS

At the end of February 2020, I set myself an objective: I had to build a “decent” set of components that can be used as a “getting started template” for future projects — named the demo cars app.

Here I am 6 months later: zero new projects, a pandemic, but … Why go back and document now? “Life Is a Journey, Not a Destination” — A famous quote will say, and after those 6 months I decided to write down my learnings, so they can be helpful for a future me and hopefully helpful to others.

Final app link : https://app-democars.cmymesh.com/

Why not using app generators like J Hipster or Spring Initializr?

Demo cars app main two objectives of this app template are:

  • Learning.
  • And have a convenient way o use those technologies in a way which I feel familiar with, we could very well start with J Hipster but the process of application appropriation.

What are the different components of the demo cars applications?

Demo cars back end services

  • Generate Controllers and models based on a Swagger spec . There is a directory api-spec where swagger-carsdemo.yaml is located. More on this next .
  • Deployment with AWS Cloud formation. These files (coming from the original AWS CodeStar template) files help application to be deployed in AWS, with minimal to no effort.

Why do I think controllers and models code generation from an API specification is important?

  • One important aspect of it is that it helps us prevent doing silly mistakes like typos when creating Java pojos or controllers declarations
  • It helps enforce standards in code generation, for something which tends to be a very manual effort.
  • It will also be used as an input template when creating the API Gateway resource in AWS API Gateway
  • It will help us automatically generate a client in the language of our preference.

How Do I add swagger resources to My Project ?

java -jar ~/bin/swagger-codegen-cli.jar generate -i api-spec/swagger-carsdemo.yaml -l spring -c config/swagger-codegen.json

Deployment with AWS CodeStar

The key files to achieve automatic AWS deployment to EC2 described below , to the original template I added an internal Network Load Balancer (NLB) LoadBalancerWebApp — which will later be used for connectivity between API Gateway and our services

  • appspec.yml — this file is used by AWS CodeDeploy when deploying the web service to EC2
  • buildspec.yml — this file is used by AWS CodeBuild to build the web service
  • scripts/ — this directory contains scripts used by AWS CodeDeploy when installing and deploying your service on the Amazon EC2 instance
  • template.yml — this file contains the description of AWS resources used by AWS CloudFormation to deploy your infrastructure
  • template-configuration.json — this file contains the project ARN with placeholders used for tagging resources with the project ID

Note: When I tried to recreate the Cloud formation resources for this demo (around 17–18 October 2020), I noticed that resources were not getting created and ended up deleting and recreating a new CodeStar project. This was the easiest way as I recognize that CodeStar is definitely doing a lot of things behind the scenes which I am not fully aware .

API Gateway integration

Now, the demo-cars-svc app is not publicly exposing any endpoint that can be used in our UI , this is as per design . The reason behind this is to expose the service via an API Gateway service which will give benefits such as centralized authentication and authorization, rate limiting , CORS management , etc . so developers can focus on what they know best and stop worrying about infrastructure aspects of service .

To get started with we need to go to AWS API Gateway and use the swagger-carsdemo.yaml as an input to generate an API in AWS API Gateway,

Image for post
Image for post
Create new API screen from Amazon API Gateway

Once we successfully imported the Api specification is time to generate a VPC Link to our app which links to the NLB created during deployment.

Image for post
Image for post
VPC Link creation

Finally, you will need to associate the VPC Link to your endpoints for URL you will need to use the DNS address from the created NLB . Details below.

Image for post
Image for post

You can use Amazon API Gateway test functionality to make sure things are working as expected , once you are comfortable with results — deploy API to a stage (see details on https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api.html).

At this point, you should have a public NON SECURED endpoint that can be used in your UI application ( if you are not using the same domain for your UI app and your services don’t forget to enable CORS support, you can do this in the API Gateway).

Lambda authentication helper lambda

There are multiple ways of doing this, two that seems natural are handle authentication directly in our service , or use API Gateway to help us with that .

API Gateway allows you to define authorizers that can be attached to your endpoints and used for authentication/authorization. Those authorizers could either be Lambda functions or a direct integration with Amazon Cognito ( I find Cognito a little bit difficult to use as is a very robust Access Control provider with so many different features that we don’t necessarily need).

I decided to implement a Lambda authorizer in order to give room for future implementations as this could give me flexibility in case I need to change the OAuth 2 provider for something different than Cognito, for example, OAuth2 login from Google account. Following this blog post , I was able to produce a working lambda demo-cars-lambda and deploy it manually using Lambda console.

Image for post
Image for post
Lambda authorizer definition

Once the authorizer is created then you can attach to a particular API Execution (don’t forget to deploy your changes).

Image for post
Image for post

Your APIs should be secured using Cognito as an OAuth provider .

If you need to test your app by hitting the endpoint from Postman , you can get a token by calling your OAuth server, you can use below curl command

curl -X POST \
- user yourUser:yourSecet \
'https://democars.auth.us-east-2.amazoncognito.com/oauth2/token?grant_type=client_credentials&scope=democars-resource-server/inspect_cars' \
-H 'Content-Type: application/x-www-form-urlencoded'

This will give you back a token , which you will need to pass in query parameter “token” when calling your API (you might wonder why a query parameter ? The reason seems to be either at the time of building the Lambda authorizer the header option wasn’t an option or other complication that I might have got when calling it from the UI).

UI app

npm install aws-amplify
npm install @aws-amplify/ui

And you can follow the steps on https://docs.amplify.aws/start/q/integration/react or https://aws.amazon.com/getting-started/hands-on/build-react-app-amplify-graphql/module-three/

For demo-cars UI App , we use the pre built UI components for authentication , just be careful that when you do

amplify add auth

And to integrate with Cognito make sure the user pool id and identity pool match the same one you configured on the lamdba authorizer.

Finally, on api-exports.js, change the endpoint to the correct API Gateway endpoint and region.

Push your changes and amplify should take care of the deployment, you can go to the Amplify console, and should look like this

Image for post
Image for post
Amplify deployment

Putting the Pieces Together

Image for post
Image for post

Resources

AWS API Gateway

AWS Amplify

Acknowledge and Thanks to

Written by

Coffee lover (serious espresso drinker)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store