Serverless Web Application

Manideep Reddy Gillela
6 min readJan 6, 2020

We’ll build a serverless web app, running a simple Python flask API in AWS Fargate and serving content out of AWS S3.

Some of the serverless services on AWS Cloud

Now a days, all the buzz is about serverless computing.

Traditional Web Hosting:

Let’s say we are using a web app or mobile app. We also need a backend and restful api, which these applications can access data. On that backend we will run our code base and reachout to database.

We will write our code to listen to incoming requests on certain API Endpoints, so on URLS we provide our servers to send requests to and our code may be written in any programming language. Here, we will be managing our servers right from provisioning to scaling them. We can handle that using our own on premise data center or using a cloud provider like AWS.

We face so many challenges using traditional hosting like patching, prevent security issues, updating and monitoring our servers. We always keep our servers updated, OS updated and have to keep software updated. And also, while doing so, we have to make sure not to break anything.

Additionally, we have to think about number of servers we need up running and our servers are also online if we don’t require them.So, there are chances of over or under-provisioning.

These are the typical challenges we face using traditional hosting.

We can fix these when hosting an API using serverless computing.

Serverless Hosting:

Serverless is a cloud computing architecture where cloud providers will provide backend services. There are servers involved but we don’t manage them at all.

We use Cloud services like AWS Lambda, AWS Fargate etc. Which allows us to host our code, which is executed on demand only when it needs to run.

Code runs in up-to-date and secure environment.

Here, we don’t need to think about servers and we don’t have to pay for any idle time.

It’s great for single page and API applications.

Before starting, you need to have an AWS account and AWS CLI configured.

Steps we follow:

  1. Create and Configure S3 bucket to host web static web content.
  2. Host our API on a container running through AWS Fargate.

Let’s start!

Clone the Github repo from here:

git clone https://github.com/manideep1116/serverless_web_application.git

Now, change the directory.

cd serverless_web_application

Create an S3 bucket and configure for web hosting. Replace the Bucket name everywhere from now onwards and it should be unique.

aws s3 mb s3://BucketName

Now, apply the bucket policy

aws s3api put-bucket-policy --bucket BucketName --policy file://~/serverless_web_application/s3/bucket-policy.json

Now, change the website hosting settings of s3 bucket. We can also do this manually as shown in the pic below.

aws s3 website s3://BucketName --index-document index.html

Now, copy your index.html file to s3 bucket.

aws s3 cp ~/serverless_web_application/static/index.html s3://serverless00/index.html

I am using a simple job portal web page. When, candidates click in the job description. The information will be fetched from the API running in the Backend.

Now, you can open this link below and check your static web page hosted. Replace region and bucket name.

http://BucketName.s3-website-REGION.amazonaws.com

We are going to run our flask api in a container through AWS Faragte.

AWS Fargate is the compute engine, it eliminates our need to manage the EC2 instances. Once we define all our application requirements, AWS Fargate manages all the scaling and infrastructure needed to run our containers with high availability.

We will be using a Network Load Balancer in front of Fargate, instead of directly accessing the Fargate.

Now, we’ll build the core stack using a CFN template. The template we are using now is from AWS Github repo. It will take more than 10 minutes.

aws cloudformation create-stack --stack-name ServerlessStack --capabilities CAPABILITY_NAMED_IAM --template-body file://~/serverless_web_application/core.yml

We can check the status from AWS console or by using the command. Wait until the status is ‘CREATE_COMPLETE’

aws cloudformation describe-stacks --stack-name ServerlessStack

Being in the same directory, run the below command to build in the docker image and tag it, so that we can push it to ECR later.

docker build . -t ACCOUNT_ID.dkr.ecr.REGION.amazonaws.com/serverless/service:latest

Create an ECR repository

aws ecr create-repository --repository-name serverless/service

Run the below command to get logic command to retrieve credentials for our Docker client to the repository. We’ll see a login succeed command.

$(aws ecr get-login --no-include-email)

Now, push our Docker Image to the ECR repository.

docker push DOCKER_IMAGE_TAG

Use this command to see the pushed image

aws ecr describe-image  —-repository-name serverless/service

This is the simple flask api we just built in the docker image

from flask import Flask, jsonify, request, render_template
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route(‘/’)
def index():
return ‘hello!’
@app.route(‘/fullstack’, methods = [‘GET’])
def fullStack():
# message = {‘greeting’:’Hello from Flask!’}
#return jsonify(message)
return “<h3>Job description </h3><p>At Ocelot, full stack developers work as a team to build modern, cloud-native products with our clients.</p> “
@app.route(‘/cloudeng’)
def cloudEng():
return “<h3>Job description</h3><p>As a cloud engineer, you will build and automate highly available, elastic, and secure cloud-based infrastructure to support the needs of our client workloads.</p>”
@app.route(‘/bigdata’)
def bigData():
return “<h3>Job description</h3><p>As a Big Data Engineer, you will develop innovative software using distributed data processing frameworks and techniques.</p>”
if __name__ == “__main__”:
app.run(host=”0.0.0.0", port=8080)
app.run()

Configure AWS ECS. Creating a cluster.

aws ecs create-cluster — cluster-name serverless-webapp

Creating a cloudwatch Logs Group to analyse the log metrics.

aws logs create-log-group — log-group-name serverless-webapp

A task in ECS is a set of container images that should be scheduled together. A task definition declares that set of containers and the resources and configuration those containers require.

aws ecs register-task-definition — cli-input-json file://task-definition.json

Create a Network Load Balancer

aws elbv2 create-load-balancer --name mysfits-nlb --scheme internet-facing --type network --subnets REPLACE_ME_PUBLIC_SUBNET_ONE REPLACE_ME_PUBLIC_SUBNET_TWO > ~/environment/nlb-output.json

Next, will create a target group. A target group allows AWS resources to register themselves as targets for requests that the load balancer receives to forward. Our service containers will automatically register to this target so that they can receive traffic from the NLB when they are provisioned.

aws elbv2 create-target-group -— name ServerlessWebapp-TargetGroup — port 8080 —- protocol TCP -— target-type ip -— vpc-id xyz -— health-check-interval-seconds 10 -— health-check-path / — health-check-protocol HTTP -— healthy-threshold-count 3 -— unhealthy-threshold-count 3 > Targetgroup-output.json

Create an NLB Listener. Listener tells the NLB about the requests received on specific port and will be forward to the specific targets as per target groups.

aws elbv2 create-listener -— default-actions TargetGroupArn=REPLACE_ME_NLB_TARGET_GROUP_ARN,Type=forward —- load-balancer-arn REPLACE_ME_NLB_ARN -— port 80 —- protocol TCP

Create the service, where our containers will be running

aws ecs create-service --cli-input-json file:/service-definition.json

Now, copy the DNS name from the nlb output and check in the browser to see the API is running. Check the subnet associations with route tables if you face any network issues.

If everything looks good, add this NLB url in the index.html in the S3 bucket. Now, we can access our content out of s3 bucket.

We can also integrate API gateway and AWS Cognito, to authenticate and authorize the users at API gateway.

Summary:

We have successfully deployed our serverless application!

References: https://aws.amazon.com/getting-started/projects/build-modern-app-fargate-lambda-dynamodb-python/

--

--

Manideep Reddy Gillela

Cloud Architect | AWS Cloud, DevOps and Data Enthusiast!