SAM CLI (Part 1) - Developing AWS Serverless Applications

SAM is a Command Line Interface (CLI) for building, testing, and deploying serverless applications written to the AWS Serverless Application Model (SAM)...

10 months ago

Latest Post Kubernetes Cheat Sheet by Tyler Moon

SAM is a Command Line Interface (CLI) for building, testing, and deploying serverless applications written to the AWS Serverless Application Model (SAM). The SAM CLI can run local environments of any Lambda Runtime by utilizing Docker containerization. This tool makes it much easier to develop serverless applications than using the AWS Console. It also has the added benefit of enabling serverless code to be easily source controlled and tested.

SAM CLI Series

Prerequisites

AWS Credentials

If you have not used the AWS CLI locally before then you will need to configure your AWS IAM credentials. The SAM CLI will use these credentials when validating your AWS account, pulling Docker images, and eventually deploying resources. The following link explains how to setup an IAM profile and store the credentials for it locally in a couple of JSON files.

https://aws.amazon.com/console/

Installing the SAM CLI

There are a few different ways to install the SAM CLI but the easiest, and operating agnostic, method is to use Python Pip.

pip install --user aws-sam-cli

Then add the CLI's bin directory to your path

After restarting your terminal the SAM CLI should now be available. Test that it is working by executing sam --version.

Project Setup

Now that we have all the prerequisites installed, including the AWS CLI and SAM CLI, its time to get started on our standard Hello World program. Navigate to a new directory and then execute sam init --runtime python3.7 to create a bootstrapped Python project.

Note: The --runtime flag allows you to select any of the many Lambda runtimes available. For this project, we are focusing on Python.

Open up the newly created directory in your editor of choice and let us take a look around. The template.yaml file defines how the function application is structured, the paths to each function, and creates a template for when the project is deployed to AWS. In the ./hello_world/app.py file is where the HelloWorldFunction is defined. This example function just returns a JSON object with a message and the IP address of the function. This can be useful for debugging deployments and as a health check URL. To really dive into how this works let us create another function and add it to the existing project. The following commands will create a new blank Lambda function.

mkdir hello_world_name && cd hello_world_name
touch __init__.py app.py requirements.txt

Even though they are required to exist in the directory we are going to leave both the __init__.py and requirements.txt files blank. Open up the app.py file and add the following Python code that will take a URL parameter called "name" and output it in a message.

# hello_world_name/app.py
import json

def lambda_handler(event, context):
    try:
        name = event['pathParameters']['name']
    except Exception as e:
        print(e)
        raise(e)
    
    return {
        "statusCode": 200,
        "body": json.dumps(
            {"message": "Hi there " + str(name) + "!"}
        ),
    }
Note: The tabs here are important as Python is a whitespace sensitive language

That defines our function but before we can test it we need to add it to the YAML definition file. Open up the template.yaml file in the project root directory and add the following below the Method: get line on line 30.

  HelloWorldNameFunction:
        Type: AWS::Serverless::Function
        Properties:
            CodeUri: hello_world_name/
            Handler: app.lambda_handler
            Runtime: python3.7
            Events:
                HelloWorld:
                    Type: Api
                    Properties:
                        Path: /hello/{name}
                        Method: get

This will tell the SAM CLI that we have a function in the hello_world_name directory that should be executed when /hello/{name} is hit. In this case {name} can be any string and will be added to the message returned from the function.

Makefile

This step is not required but I have found that using a Makefile can be useful when switching between different project types so that you do not have to remember all the CLI commands. In the project root directory create a file Makefile and add the following.

build:
	sam build --use-container
run:
	sam local start-api

deploy:
	echo "Not Implemented Yet"

Build and Test Locally

After all that setup and coding its finally time to see these Lambda functions in action. Run make build to create the runtime package and download the needed Docker containers that will be used to execute the functions. Then execute make run and your Python functions should be available at http://127.0.0.1:3000. Try out /hello to see the function that was generated. Then try navigating to /hello/<insert_name> where you replace the last part with your name. The function should return a JSON object with a message containing a greeting addressed to you!

Summary

In this tutorial, we saw how to set up the AWS SAM CLI to develop and test AWS Lambda functions locally. There was a good bit of setup but once you have the tools installed it is very easy to develop serverless applications.

In part 2 of this series we will cover how to use the SAM CLI to deploy this project to AWS using the Amazon CloudFormation Infrastructure as Code system.

Tyler Moon

Published 10 months ago

Comments?

Leave us your opinion.