Serverless Applications with AWS Fargate

on
nov 11, 2018
in
AWS

This blog shows how to create serverless applications that run continuously. We will call this type of application a
Serverless Continuous Running Application or (SCRA). This type of application has almost no limit on compute,
memory or code archive size. In this blog we will create a simple web service using Python and Flask.
The web service will be run as a SCRA and be deployed to Amazon Elastic Container Service (ECS)
and executed on Amazon Fargate.

Continuously vs Event Driven

There are differences between Serverless Functions (SF) and SCRA. SF like AWS Lambda are event-driven,
run on demand and have restrictions on the code size, programming language and execution time limit. SCRA do not have
these limitations. SCRA run continuously, have no limit on the code size and programming language that can be used.
What the two models have in common is that you only pay for what you use, do not manage servers and that the service
scales automatically.

ECS and Fargate

SCRA are packaged and run leveraging Docker technology. To run, scale and manage the SCRA
an orchestrator is necessary that decides where to run the application in the data center. AWS provides a free and serverless
orchestrator called Amazon Elastic Container Service (ECS). In april 2018 AWS Fargate was introduced,
which is a serverless compute engine for container workloads on AWS. Up until the release of Fargate, it was necessary to provide
and manage a fleet of virtual machines to run the docker containers. Now we have a choice, manage our own fleet of virtual
machines to run the containers on, and/or run the container on Fargate.

Deploying a serverless application

Deploying a SCRA on AWS involves creating the following resources:

  • creating an ECR docker registry,
  • building and uploading the container image to the registry,
  • creating a VPC,
  • creating an ECS cluster,
  • creating an ECS task definition that defines:
  • awsvpc as the networking mode,
  • FARGATE as compatibility,
  • creating an ECS service definition that defines:
  • FARGATE as the launch type,
  • an IAM role for the ECS Task that has access to ecr and logs,
  • an IAM role for the ECS cluster, that has access to ec2 in order to create network interfaces,
  • a security group that allows access to the ECS service

The actors web service

Flask makes it easy to define web service using Python. The code for the ‘actors’ web service is shown below.

from flask import Flask, jsonify
from flask_basicauth import BasicAuth

app = Flask(__name__)

app.config['BASIC_AUTH_USERNAME'] = 'user'
app.config['BASIC_AUTH_PASSWORD'] = 'password'
app.config['BASIC_AUTH_FORCE'] = True
basic_auth = BasicAuth(app)

actors = [
    {'id': 1, 'actor': 'William Shatner', 'role': 'James T'},
    {'id': 2, 'actor': 'Leonard Nimoy', 'role': 'Spock'},
    {'id': 3, 'actor': 'DeForest Kelley', 'role': 'Leonard McCoy'},
    {'id': 4, 'actor': 'James Doohan', 'role': 'Montgomery Scott'},
    {'id': 5, 'actor': 'George Takei', 'role': 'Hikaru Sulu'},
    {'id': 6, 'actor': 'Walter Koenig', 'role': 'Pavel Chekov'},
    {'id': 7, 'actor': 'Nichelle Nichols', 'role': 'Nyota Uhura'},
    {'id': 8, 'actor': 'Majel Barrett', 'role': 'Christine Chapel'}
]

@app.route('/actors', methods=['GET'])
def get_persons():
    return jsonify(actors), 200

@app.route('/actors/<int:id>', methods=['GET'])
def get_actor_by_id(id: int):
    found = None
    for actor in actors:
        if actor['id'] == id:
            found = actor
            break

    if found:
        return jsonify(found), 200
    else:
        return '', 404


app.run(debug=True, host="0.0.0.0", port=5000)

Example

The example project shows how to create an ECS cluster
running a service on Fargate as a SCRA. I assume you have a mac with python, pipenv, sceptre installed. To deploy
the example type make deploy. To get the ip address of the running container type make get_ip.
To remove the example type make delete.
The web service can be invoked using any http client like httpie:

$ http -a user:password http://<replace-with-ip-address>:5000/actors
HTTP/1.0 200 OK
Content-Length: 658
Content-Type: application/json
Date: Sun, 11 Nov 2018 10:28:41 GMT
Server: Werkzeug/0.14.1 Python/3.7.0
[
    { "actor": "William Shatner", "id": 1, "role": "James T" },
    { "actor": "Leonard Nimoy", "id": 2, "role": "Spock" }, 
    { "actor": "DeForest Kelley", "id": 3, "role": "Leonard McCoy" },
    { "actor": "James Doohan", "id": 4, "role": "Montgomery Scott" }, 
    { "actor": "George Takei", "id": 5, "role": "Hikaru Sulu" }, 
    { "actor": "Walter Koenig", "id": 6, "role": "Pavel Chekov" }, 
    { "actor": "Nichelle Nichols", "id": 7, "role": "Nyota Uhura" }, 
    { "actor": "Majel Barrett", "id": 8, "role": "Christine Chapel" }
]

Conclusion

Serverless Continuous Running Applications (SCRA) are applications that run continuously. These applications can be
deployed using Amazon ECS and Fargate. SCRA need infrastructure in order to communicatie with other services like
web clients or databases. In this blog we looked at creating a simple ‘actors’ web service that runs as a serverless
application on Amazon Fargate. Next time we’ll deploy the ‘actors’ web service to Google App Engine.

Share this article: Tweet this post / Post on LinkedIn