AWS Startups Blog

Introducing the ‘Startup Kit Serverless Workload’

“What’s the easiest way to get started on AWS?” is a common question. Although there are many well established paths to getting started, including using AWS Elastic Beanstalk, serverless computing is a rapidly growing alternative.

Serverless computing allows you to build and run applications and services without thinking about servers. On AWS, the AWS Lambda service is the central building block for serverless computing. AWS also provides several other services to support serverless architectures. These include Amazon API Gateway, which you can use with Lambda to create a RESTful API, and Amazon DynamoDB, a NoSQL cloud database service that frees you from the burden of setting up a database cluster.

A completely serverless architecture is shown in the following diagram.

 

serverless architecture AWS

 

The bottom group of services in the diagram implement a RESTful API service. API Gateway processes API requests and responses, mapping them to Lambda functions that implement business logic. DynamoDB is the persistence layer. The group of services at the top of the diagram form the frontend. Amazon S3 hosts static website assets, such as an AngularJS or React app, and is a fully managed service that eliminates the need to run a fleet of frontend servers. In front of S3 is Amazon CloudFront, a content delivery network (CDN) for efficient delivery of website content from edge locations close to users all around the world.

Until recently, one of the concerns with implementing serverless applications was how to deploy them efficiently. However, there is now an AWS native solution: AWS Serverless Application Model (AWS SAM). Using AWS SAM, you can easily manage your serverless deployment using a simple YAML-based description language and just two AWS CLI commands. Going serverless might now be the easiest way to get started on AWS, especially for those unfamiliar with managing infrastructure.

In this post, I introduce the first component of a larger initiative: the AWS Startup Kit. The Startup Kit provides prescriptive guidance about how to get started on AWS, and includes several example workloads that use technologies commonly employed by startups. A “workload” is one or more related applications running on AWS that provide business or operational value, such as a RESTful API exposed to your customers, a batch processing job for analytics, and so on.

The Startup Kit component discussed in this post is the Startup Kit Serverless Workload:  a sample RESTful API for a TODO app built using the Lambda Node.js 4.3 runtime and deployed with SAM. You can check out the code itself on GitHub in the startup-kit-serverless-workload repository. If you haven’t already done so, you’ll need to set up an AWS account and install the AWS CLI (details here).

 

Serverless Architecture Benefits

By using a serverless architecture, you’ve gained many of the benefits of the AWS Well-Architected framework. Although a complete, in-depth Well-Architected review is beyond the scope of this post, it’s worthwhile to briefly look at how the five pillars of the framework apply to this architecture.

In the following summary chart, “HA” means high availability, “OS” is operating system, and “IAM” refers to the AWS Identity and Access Management service, which enables you to securely control access to AWS services and resources.

API Gateway

     Lambda

     DynamoDB

Security

HTTPS by default.

Throttling of calls can be specified.

Secure calls with IAM or bearer token auth.

AWS managed OS.

A Lambda function’s access to other AWS resources is limited by IAM role(s) assigned to it.

IAM can be used to provide fine-grained access controls for DynamoDB resources.

Calls to DynamoDB can be tracked with AWS CloudTrail.

Reliability

 AWS managed HA and scaling.

Calls are not throttled unless otherwise specified.

AWS managed HA and scaling.

Failed asynchronous invocations are retried, and may be placed in a dead letter queue (DLQ).

AWS managed HA and scaling.

Data is replicated three times in an AWS Region.

Performance Efficiency

Result caching can be enabled.

Serverless resources consumed only as needed.

 

Serverless resources are consumed only as needed.

 

Serverless resources are consumed only as needed.

Cost Optimization

 No need to run a fleet of reverse proxies to route API calls. Cost is a function of up time; no charge if not doing work.

No cluster management.

No need to guess hardware capacity.

Operational Excellence

Automate with SAM.

Easy management of API versioning and deployment.

Basic metrics provided; logging can be enabled.

Automate with SAM.

Basic metrics provided in the Lambda console.

Logs accessed by link in the Lambda console, or by going directly to the Amazon CloudWatch console.

Automate with SAM.

Basic metrics provided in the DynamoDB console.

DynamoDB Streams can be used to track changes to tables.

The preceding analysis just scratches the surface of the Well-Architected framework. As you move forward with building your serverless architecture on AWS, be sure to consult the Well-Architected framework’s whitepaper for additional considerations and ways to improve your architecture.

 

Using SAM to Deploy the Workload

SAM is a model for defining serverless applications. To use SAM, describe your serverless resources using YAML (or JSON) syntax in a template file, then package and deploy your code using a pair of AWS CLI commands. SAM itself is an open-source project, and is available on GitHub.

Three basic kinds of serverless resources are supported by SAM: “Function” (via Lambda), “Api” (via API Gateway), and “SimpleTable” (via DynamoDB). SAM also allows specification of event sources for Functions (such as an Api), and properties such as environment variables for Functions. To further simplify your SAM template, specify an Api as an event source for a Function. If you do so, there is no need to explicitly declare an Api resource because SAM will set it up for you.

The SAM template below shows how simple it is to specify a Function resource. The first Function, CreateFunction, implements an API call to create a new TODO item in the TODO app’s DynamoDB table. CreateFunction’s relationship to the rest of the serverless application is fully specified in the SAM template. For example, to specify how CreateFunction interacts with the DynamoDB table, the template associates with CreateFunction an IAM policy that includes DynamoDB write permissions, and also specifies an environment variable that references the DynamoDB table. An Api event is specified for invoking CreateFunction. This event is described by the path and HTTP method, in this case POST. The other Functions in the SAM template all follow the same basic pattern.

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: RESTful API for a TODO app, backed by a SimpleTable (DynamoDB) resource.

Resources:
  
  CreateFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.create
      Runtime: nodejs4.3
      Policies: AmazonDynamoDBFullAccess
      Environment:
        Variables:
          TABLE_NAME: !Ref Table
      Events:
        PostResource:
          Type: Api
          Properties:
            Path: /todo/new
            Method: post

  GetAllFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.getAll
      Runtime: nodejs4.3
      Policies: AmazonDynamoDBReadOnlyAccess
      Environment:
        Variables:
          TABLE_NAME: !Ref Table
      Events:
        GetResource:
          Type: Api
          Properties:
            Path: /todo/all
            Method: get

  # API functions related to active TODO items
  
  GetActiveFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.getActive
      Runtime: nodejs4.3
      Policies: AmazonDynamoDBReadOnlyAccess
      Environment:
        Variables:
          TABLE_NAME: !Ref Table
      Events:
        GetResource:
          Type: Api
          Properties:
            Path: /todo/active
            Method: get

  UpdateActiveFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.updateActive
      Runtime: nodejs4.3
      Policies: AmazonDynamoDBFullAccess
      Environment:
        Variables:
          TABLE_NAME: !Ref Table
      Events:
        PutResource:
          Type: Api
          Properties:
            Path: /todo/active
            Method: put

  # API functions related to completed TODO items
  
  GetCompleteFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.getComplete
      Runtime: nodejs4.3
      Policies: AmazonDynamoDBReadOnlyAccess
      Environment:
        Variables:
          TABLE_NAME: !Ref Table
      Events:
        GetResource:
          Type: Api
          Properties:
            Path: /todo/complete
            Method: get

  MarkCompleteFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.markComplete
      Runtime: nodejs4.3
      Policies: AmazonDynamoDBFullAccess
      Environment:
        Variables:
          TABLE_NAME: !Ref Table
      Events:
        PutResource:
          Type: Api
          Properties:
            Path: /todo/complete
            Method: put

  DeleteCompleteFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.deleteComplete
      Runtime: nodejs4.3
      Policies: AmazonDynamoDBFullAccess
      Environment:
        Variables:
          TABLE_NAME: !Ref Table
      Events:
        DeleteResource:
          Type: Api
          Properties:
            Path: /todo/complete
            Method: delete

  Table:
    Type: AWS::Serverless::SimpleTable
    Properties:
      PrimaryKey:
         Name: todo_id
         Type: String
      ProvisionedThroughput:
         ReadCapacityUnits: 5
         WriteCapacityUnits: 5

Before you start, make sure to either install the AWS CLI, or update the version you have installed previously:  some commands used in this post may not exist in older versions of the AWS CLI. The IAM user you associate with the AWS CLI should have admin permissions, including the ability to create IAM roles.

To begin your deployment of the Startup Kit Serverless Workload, either download a zip file of the code from GitHub or clone the GitHub repository with this command:

git clone https://github.com/awslabs/startup-kit-serverless-workload.git

In the AWS Region where you plan to do your deployment, be sure you have an existing Amazon S3 bucket in which SAM can put the deployment artifacts, or create a new bucket using the following AWS CLI command:

aws s3 mb s3://<your-bucket-name>

Next, simply run the following two AWS CLI commands. For the first command, package, replace the s3-bucket argument with the name of your S3 bucket. For the second command, deploy, replace the template-file argument with the full path to your output template file:

aws cloudformation package \
--template-file serverless.cfn.yml \
--output-template-file serverless-xfm.cfn.yml \
--s3-bucket <your-bucket-name>
aws cloudformation deploy 
--template-file <path-to-file/serverless-xfm.cfn.yml> \
--stack-name StartupKitServerless \
--capabilities CAPABILITY_IAM

After the deploy command indicates it has finished, your workload is up and running! These two commands are the core of the deployment workflow when working with SAM.

For example, if you modify the code and want to deploy the changes, simply execute the package and deploy the commands again.

Next, to test your workload, get the invoke URL of your API. To do this, execute the following Bash code by copying and pasting it into your terminal, replacing the AWS region code “us-west-2” with your current region if different (e.g. us-east-1), then hitting return:

x=`aws cloudformation list-stack-resources --stack-name StartupKitServerless | grep -A2 'AWS::ApiGateway::RestApi' | grep 'PhysicalResourceId' | awk '{print $2}' | tr -d '"' | tr -d ","`; echo "https://$x.execute-api.us-west-2.amazonaws.com/Stage/"

(An alternative way to get the invoke URL:  go to the API Gateway console, choose StartupKitServerless, choose Stages in the left navigation pane, and then choose Stage in the list of stages. The API’s invoke URL should now appear in the upper-right pane; copy the entire URL, including the “/Stage” at the end.)

Begin testing by adding some TODO items using the create API. This may be accomplished using the following command:

curl -X POST -H 'Content-Type: application/json' -d '{"todo_id": "1001", "active": true, "description": "What TODO next?"}' https://<invoke-URL-for-your-API>/todo/new

To fetch the active TODO items you created, execute the following command:

curl https://<invoke-URL-for-your-API>/todo/active

Similar commands can be used to test all of the other API calls.

 

Stay tuned . . .

Using AWS SAM and serverless architectures is one of the easiest ways to get started on AWS. If you have any suggestions, comments, or corrections regarding the Startup Kit Serverless Workload, please submit a pull request on GitHub. This is just the beginning of the Startup Kit story – more content is on the way!

 

Special thanks to Itzik Paz for providing the Bash code to retrieve the invoke URL