The AWS Serverless Application Model, also referred to as AWS SAM, is an open-source framework that allows you to build your serverless applications quickly and easily. Throughout this guide, we will look at the benefits of AWS SAM and how it works, including a fully working example to demonstrate. We have lots to cover, so let's get started!
Latest posts by Graham Beer (see all)

Why the AWS Serverless Application Model?

The AWS Serverless Application Model integrates with many other AWS resources to make building your Serverless application easier. Using AWS Cloud 9, which we will do, allows you to have a fully functioning IDE with the AWS SAM CLI and AWS CLI (among others) preinstalled. Using CodeBuild, CodeDeploy, and CodePipeline provides a mechanism to build a safe deployment pipeline.

AWS SAM is an extension of AWS CloudFormation and is Python based. We can define additional resources using CloudFormation inside our SAM template. In fact, anything available to use in CloudFormation, such as templates and intrinsic functions, is available in SAM. One other area to note is local debugging and testing. There are toolkits available for many popular IDEs, such as VSCode, which help to make debugging, testing, and deploying easier.

Using Cloud 9 to use AWS SAM

Instead of just talking about AWS SAM, let's dive in and start to understand what we are working with. I'm going to use Cloud 9 in this demo so that we will have a fully working environment, as opposed to downloading and installing the software locally.

Cloud 9 from AWS is an IDE for writing, running, and debugging code built on an underlying EC2 instance. If this is not something you have done before, check out the getting started guide by AWS.

Our project for this demo will look at AWS SAM's Hello World template. The Hello World application has a basic API backend that uses the Amazon API Gateway and a Lambda function. We can then send a GET request to the API gateway to invoke our lambda, which will return a message and our IP address.

There is a lot to take in and look at, so this will be a good place to start.

From your IDE, type sam init. This initializes a serverless application with an AWS SAM template:

Getting started sam init

Getting started sam init

You can pass arguments to the sam init command to skip some or all of the menu options. Take a look here to see some examples.

AWS SAM prompts you to provide the following information:

Going through the SAM options

Going through the SAM options

The source template for this demo will be AWS Quick Start Templates, so select Option 1. Next, we are asked how we want to package our app, either a zip file or an image uploaded to Amazon Elastic Container Registry service, also known as ECR. Select the zip package option. A list of runtimes that are available to use for our Lambda is displayed. I will choose Go. After choosing our runtime, we must add a project name.

Lastly, select the Hello World Example to complete the setup.

Completion with summary

Completion with summary

Once the project has been initialized, the folder structure will look as follows:

AWS SAM project structure

AWS SAM project structure

The key areas are the folder named after our application (hello-world), which contains the main code, and the template.yaml, which defines our application's AWS resources.

The code

The main.go file generated by our SAM project contains the following:

package main
import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

var (
	// DefaultHTTPGetAddress Default Address
	DefaultHTTPGetAddress = "https://checkip.amazonaws.com"

	// ErrNoIP No IP found in response
	ErrNoIP = errors.New("No IP in HTTP response")

	// ErrNon200Response non 200 status code in response
	ErrNon200Response = errors.New("Non 200 Response found")
)

func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	resp, err := http.Get(DefaultHTTPGetAddress)
	if err != nil {
		return events.APIGatewayProxyResponse{}, err
	}

	if resp.StatusCode != 200 {
		return events.APIGatewayProxyResponse{}, ErrNon200Response
	}

	ip, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return events.APIGatewayProxyResponse{}, err
	}

	if len(ip) == 0 {
		return events.APIGatewayProxyResponse{}, ErrNoIP
	}

	return events.APIGatewayProxyResponse{
		Body:       fmt.Sprintf("Hello, %v", string(ip)),
		StatusCode: 200,
	}, nil
}

func main() {
	lambda.Start(handler)
}

The code example contains a simple handler function that will return a message of hello along with your IP address if successful. There are some error checks in the form of if statements to handle an unsuccessful return.

Template.yaml

Looking at template.yaml, you could mistakenly think it just looks like a typical CloudFormation template, and you would be right. The AWS SAM template closely follows the CloudFormation template but with a few differences. Below is the template for our project:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  hello-sam

  Sample SAM Template for hello-sam

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 5

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello-world/
      Handler: hello-world
      Runtime: go1.x
      Architectures:
        - x86_64
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Events:
        CatchAll:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: GET
      Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
        Variables:
          PARAM1: VALUE

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldAPI:
    Description: "API Gateway endpoint URL for Prod environment for First Function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "First Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

The first thing to notice is the declaration transform, Transform: AWS::Serverless-2016-10-31, which identifies the CloudFormation template as an AWS SAM template.

The AWS SAM template has a Globals section that is not available with a CloudFormation template. This is where we add properties that are common to Serverless and APIs. We can define properties in the Globals section that we will use in the Resources section.

The Resource section can contain resources from CloudFormation as well as SAM. Sam has five special resources in AWS SAM Template properties:

  • AWS::Serverless::Function
  • AWS::Serverless::Api
  • AWS::Serverless::SimpleTable
  • AWS::Serverless::LayerVersion
  • AWS::Serverless::Application

SAM also has a Parameter section. The SAM cli has a sam deploy --guided command to prompt the user for any additional information. We can define objects in the Parameter section to prompt the user for this extra information.

Building the application

To test our Serverless application or deploy it, we need to build it. To build our application, we can call the sam build command. The SAM build command will process our template.yaml, application code, and any dependencies.

When you run the sam build command, you will see output similar to the screenshot below, depending on your runtime:

Running the sam build command

Running the sam build command

Once the build has been completed, the source code can be found in the .aws-sam sub-directory.

Testing your application

We can test our application before deploying it into AWS. AWS SAM provides us with a command, sam local, that will run our application using Docker containers. The containers used simulate the execution of AWS Lambda. You will need to have Docker installed on your machine, or if, like me, you are using AWS Cloud 9, you will have Docker available out of the box.

From the Hello-sam project folder, type the following command:

Sam local invoke

Again, output similar to that shown below will be displayed:

Invoking the sam local command

Invoking the sam local command

Notice the last line to be displayed to the terminal. We have a StatusCode of 200 and a message at the end saying hello along with an IP address. This confirms that our Lambda application is working as expected.

We are now ready to deploy!

Deploying the application to AWS

We've confirmed our application is working and is now ready to deploy. Using the SAM CLI, we can run sam deploy –guided. SAM will prompt for arguments to deploy our application. The screenshot below shows what information is required.

Sam deploy using guided switch

Sam deploy using guided switch

Once SAM has the required information, it will start to create an IAM role and move the zipped application to S3.

The deployment on screen will first show what the CloudFormation template will be building:

Deployment screen

Deployment screen

The deployment will then carry on and start to build out your Lambda application, providing the steps and the status to the screen. If you have worked with CloudFormation, then this screen will look very familiar to you.

Deployment completion screen

Deployment completion screen

The SAM template, being CloudFormation, can be viewed from the console:

AWS SAM application viewed in CloudFormation

AWS SAM application viewed in CloudFormation

It is always interesting to view the Template tab. Switching the toggle to view processed template shows how much AWS SAM has done for us. Our SAM template file has doubled in size, from 44 lines of code to 98!

In addition to being able to see our build template in AWS CloudFormation, we can also view our Lambda application on the AWS Lambda console page.

Using the API endpoint URL from either the output screen of our SAM deployment or from the configuration section in the Lambda function inside the console, we can use the application inside the browser:

Using the browser for the application

Using the browser for the application

Summary

This article's intention was to provide you with a good foundation for getting up and running with AWS SAM. SAM allows you to focus on Lambda code and make building out other resources, such as API gateway, easier. You only have to write a few lines; SAM will then transform and expand the syntax into CloudFormation, building out your application faster. Having the ability to test applications through a Docker container is convenient and helpful.

There is a lot more to the AWS Serverless Application Model, which is worth exploring. I would recommend the AWS Serverless Application Repository, where you can discover and deploy ready-made apps and code samples.

0 Comments

Leave a reply

Please enclose code in pre tags

Your email address will not be published.

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account