In this module you'll learn about the Serverless Application Model (SAM) and how you can use it to define a serverless RESTful API. You will also use SAM CLI to locally develop and rapidly test an API.
AWS SAM is a model used to define serverless applications on AWS.
Serverless applications are applications composed of functions triggered by events. A typical serverless application consists of one or more AWS Lambda functions triggered by events such as object uploads to Amazon S3, Amazon SNS notifications, and API actions. Those functions can stand alone or leverage other resources such as Amazon DynamoDB tables or S3 buckets. The most basic serverless application is simply a function.
AWS SAM is based on AWS CloudFormation. A serverless application is defined in a CloudFormation template and deployed as a CloudFormation stack. An AWS SAM template is a CloudFormation template.
AWS SAM defines a set of resources that describe common components of serverless applications. In order to include objects defined by AWS SAM within a CloudFormation template, the template must include a Transform
section in the document root with a value of AWS::Serverless-2016-10-31
.
The Unicorn API includes Amazon API Gateway HTTP endpoints that trigger AWS Lambda functions that read and write data to an Amazon DynamoDB database. The SAM template for the Unicorn API describes a DynamoDB table with a hash key and Lambda functions to list, view and update Unicorns in the Wild Rydes stable.
In this module, you will be working with a Lambda function that simply displays a welcome message. The Unicorn API components are defined in the template.yml SAM template. Next we'll review the Lambda function component in more detail.
Below is a code snippet from the SAM template to list Unicorns:
ListFunction:
Type: 'AWS::Serverless::Function'
Properties:
FunctionName: 'uni-api-list'
Runtime: nodejs8.10
CodeUri: app
Handler: list.lambda_handler
Description: List Unicorns
Timeout: 10
Events:
GET:
Type: Api
Properties:
Path: /unicorns
Method: get
Role: !GetAtt LambdaExecutionRole.Arn
There are several properties defined for the AWS::Serverless::Function resource, which we'll review in turn.
The FunctionName property defines a custom name for the Lambda function. If not specified, CloudFormation will generate a name using the CloudFormation Stack name, CloudFormation Resource name, and random ID.
The example API shown above is implemented in Node.js 8.10. Additional runtimes are available for AWS Lambda. Please refer to the Lambda Execution Environment and Available Libraries for the complete list.
The CodeUri property defines the location to the function code on your workstation relative to the SAM template. In this example, "app" is used for the property value because the function code is in the app
directory relative to the SAM template.
The Handler property defines the entry point for the Lambda function. For Javascript, This is formatted as "file.function", where file is the Javascript filename without the ".js" extension relative to the CodeUri path defined above and function is the name of the function in the file that will be executed with the Lambda function is invoked.
The Events property defines the sources that trigger the Lambda function invocation. An Api event source is defined to integrate the Lambda function with an API Gateway endpoint, however SAM supports Lamdba function triggers from a variety of sources.
The Api event source to view details of a Unicorn is defined at the RESTful resource /unicorns/{name}
accessed using the HTTP GET method. SAM will transform the Api event to an API Gateway resource and map the name value in the URL to a pathParameter in the event used to invoke the Lambda function.
The Role property defines the IAM Role that specifies the access permissions to AWS resources in the Lambda execution policy. For each project, CodeStar generates a Lambda execution role that has access to a default set of AWS resources. This role can be modified with additional policies.
Each of the following sections provide an implementation overview and detailed, step-by-step instructions. The overview should provide enough context for you to complete the implementation if you're already familiar with the AWS Management Console or you want to explore the services yourself without following a walkthrough.
If you're using the latest version of the Chrome, Firefox, or Safari web browsers the step-by-step instructions won't be visible until you expand the section.
-
In the AWS Management Console, click Services then select IAM under Security, Identity, & Compliance.
-
Click the Search IAM search box.
-
Type
CodeStarWorker-uni-api-CloudFormation
in the search box and select CodeStarWorker-uni-api-CloudFormation in the left navigation. -
In the IAM Role Summary page, click the Attach policies button.
-
Type
AWSLambdaFullAccess
in the filter text box, select the checkbox to the left of the AWSLambdaFullAccess IAM Role, and click Attach policy. -
Upon returning to the IAM Role Summary page, note that the AWSLambdaFullAccess policy has been added to the Role.
-
Each module has corresponding source code used to seed the CodeCommit Git repository for the CodeStar project. To seed the CodeCommit Git repository, click on the Launch Stack button for your region below:
Region Launch US East (N. Virginia) US West (N. California) US West (Oregon) EU (Ireland) EU (Frankfurt) Asia Pacific (Sydney) -
The CloudFormation template has been prepopulated with the necessary fields for this module. No changes are necessary
-
Select the I acknowledge that AWS CloudFormation might create IAM resources. checkbox to grant CloudFormation permission to create IAM resources on your behalf
-
Click the Create button in the lower right corner of the browser window to create the CloudFormation stack and seed the CodeCommit repository.
-
There will be a short delay as the Git repository is seeded with the new source code. Upon successful completion, the CloudFormation will show Status
CREATE_COMPLETE
.
Now that the CodeCommit Git repository has been seeded with new source code, you will need to fetch the changes locally so that you may modify the code. Typically, this is accomplished using the git pull
command, however for the workshop we have replaced the repository with a new history and different Git commands will be used.
Using your preferred Git client, run the commands on your local uni-api
Git repository:
git fetch --all
git reset --hard origin/master
AWS SAM CLI is the AWS CLI tool for managing Serverless applications written with Serverless Application Model (SAM). SAM CLI can be used to test functions locally, start a local API Gateway from a SAM template, validate a SAM template, and generate sample payloads for various event sources.
To complete this module, you will need to install SAM CLI. If you already have SAM CLI installed, you can skip this section.
Running Serverless projects and functions locally with SAM CLI requires Docker to be installed and running. SAM CLI will use the DOCKER_HOST
environment variable to contact the docker daemon.
- macOS: Docker for Mac
- Windows: Docker Toolbox
- Linux: Check your distro's package manager (e.g. yum install docker)
For macOS and Windows users: SAM CLI requires that the project directory (or any parent directory) is listed in Docker file sharing options.
Verify that docker is working, and that you can run docker commands from the CLI (e.g. docker ps
). You do not need to install/fetch/pull any containers - SAM CLI will do it automatically as required.
The easiest way to install sam
is to use pip.
To use pip, you must have Python installed and added to your system's Environment path.
pip install aws-sam-cli
Verify the installation worked:
sam --version
We also release the CLI as binaries that you can download and instantly use. You can find them under Releases in the SAM CLI repo.
If you're unable to install SAM CLI on your workstation, you may find it easier to use SAM CLI on an Amazon Linux EC2 instance. In this case, you will not be performing work locally on your laptop, instead you will connect remotely into an EC2 instance to perform editing and testing.
-
Create a keypair, if you do not have one already.
-
To launch an EC2 instance with the required dependencies, click on the Launch Stack button for your region below. You will need to select the keypair that you created in the previous step, as well as a VPC and Subnet for your EC2 instance:
Region Launch US East (N. Virginia) US West (N. California) US West (Oregon) EU (Ireland) EU (Frankfurt) Asia Pacific (Sydney) -
Once the CloudFormation stack creation has completed, find the EC2 instance public DNS name by selecting the checkbox to the left of the DeveloperInstance Stack, and clicking the Outputs tab below the list of Stacks. Find the output key labeled
PublicDnsName
and use the corresponding value in order to access the EC2 instance. -
Use SSH client to connect to the instance. If you are using Windows, use a client such as Putty or Bitvise (you can find instructions for connecting from Windows using Putty here: Connecting to Your Linux Instance from Windows Using PuTTY)
-
The Git repository has been cloned to the home directory on launch,
/home/ec2-user/uni-api
.
SAM CLI can start an HTTP server locally on EC2 instance on port 3000. In order to view content on that HTTP server through the browser on your laptop, you need to configure port forwarding.
On your workstation, open a new terminal and run the following command. In the command, replace ~/mykeypair.pem with the location and file name of your .pem file and replace ec2-###-##-##-###.compute-1.amazonaws.com with the public DNS name of your EC2 developer instance:
ssh -i ~/mykeypair.pem -N -L 3000:localhost:3000 ec2-user@ec2-###-##-##-###.compute-1.amazonaws.com
-
In your putty configuration, select Connection , SSH , Tunnels and add a mapping:
Source port: 3000 Destination: 127.0.0.1:3000
The configuration should look like this:
-
In Profile window, select C2S tab, create an entry with this configuration:
Listen Interface: 127.0.0.1 List. Port: 3000 Destination Host: localhost Dest. Port: 3000
C2S configuration should look similar to this:
In this section, you will use SAM CLI on your workstation to run the Unicorn API and test changes to it without having to deploy to AWS.
-
From the
uni-api
directory, run the following command:sam local start-api
If port forwarding from an EC2 developer instance, run the following command:
sam local start-api --host 0.0.0.0
This will spawn a local API Gateway to test HTTP request/response functionality. Features hot-reloading to allow you to quickly develop, and iterate over your functions.
sam
will automatically find any functions within your SAM template that haveApi
event sources defined, and mount them at the defined HTTP paths.If this is your first time running SAM CLI, there will be a delay as the Docker images are downloaded. Once successful, you should see output similar to the screenshot below:
-
Open a browser and enter
http://127.0.0.1:3000/unicorns
in the address bar. Confirm that you see the output below:
Congratulations! You have successfully used SAM CLI to start a local development environment. Keep the window open that is running the sam local start-api
command until this module is complete.
Next, let's look at how you can use SAM CLI to test changes to your API.
Goal: Update app/list.js
to change the welcome message to Hello re:Invent!
. Remember, the local API Gateway supports hot-reloading of code changes. There is no need to restart the sam local start-api
process to see changes.
HOW TO update code and verify results (expand for details)
Congratulations! You've successfully test changes to a Lambda function in a local development environment. You may now kill the SAM CLI running process.
To learn more about development with SAM CLI, check out AWS Documentation and SAM CLI GitHub repository.
You have successfully performed local development and testing of a RESTful serverless API using the Serverless Application Model. Please close the window running the sam local start-api
command before preceding to the next module.
In the next Continuous Delivery Pipeline Module, you will learn how to setup deployment of that API into AWS and to automate this deployment process using AWS CodePipeline and AWS CodeBuild.