DEV Community

Introduction to AWS SAM (Serverless Application Model)

I've decided to repost an article I originally published on my blog here two years ago, but this isn't just a simple repost. After rereading the original pieces, labeled as '22 min read' and '20 min read,' I realized updates were necessary. Consequently, I've thoroughly reviewed, updated, and reorganized all the content to ensure it remains relevant and up-to-date.

I will create an AWS SAM series featuring 3 articles:

  • Introduction to AWS SAM (Serverless Application Model)
  • How to create serverless applications with AWS SAM (Serverless Application Model)
  • How to add CI/CD to my SAM project

This will be my first series of articles here.


Introduction

The first thing to understand is the relationship between serverless applications and AWS SAM, followed by a review of the basics.

What is a serverless application?

A serverless application is more than just a Lambda Function. It is a combination of Lambda functions, event sources, APIs, databases, and other resources that work together to perform tasks.

What is AWS SAM?

The AWS Serverless Application Model (AWS SAM) is an open-source framework that you can use to build serverless applications on AWS. SAM is an extension of AWS CloudFormation but SAM is streamlined and specifically designed for Serverless resources.

SAM is the specific IaC solution of AWS for defining and deploying serverless applications.

Benefits of SAM

  • Local Testing and Debugging
    • With the aws sam cli you can execute and test your serverless applications on your local environment (by mounting a docker image and running the code)
  • Extension of AWS Cloud Formation
    • You get reliability on the deployment capabilities
    • You can use the SAM yaml template with all of the resources that are available in CloudFormation
  • Single Deployment Configuration
    • You can easily manage all your necessary resources in one single place that belongs to the same stack
  • Built-in best practices
    • You can define and deploy your Infrastructure as Config
    • you can enforce code reviews
    • you can enable safe deployments through CodeDeploy
    • you can enable tracing by using AWS X-Ray
  • Deep integration with development tools
    • AWS Serverless Application Repository: discover new applications
    • AWS Cloud9 IDE: For authoring, testing, and debugging. I have written a post about Cloud9; you can find it here
    • CodeBuild, CodeDeploy, and CodePipeline: To build a deployment pipeline
    • AWS CodeStar: To get started with a project structure, code repository, and a CI/CD pipeline that's automatically configured for you

Basics

We will use NodeJS as programming language. However, as AWS Says in the FAQs, you can use AWS SAM to build serverless applications that use any runtime supported by AWS Lambda.

To understand the code structure of the SAM projects, five files are particularly important:

  • Common to all the programming languages:
  1. template.yaml: This file contains the AWS SAM template that defines your application's AWS resources.
  2. events/file.json: events folder contains the invocation events that you can use to invoke the function.
    • Depends on the programming language (in this case NodeJS), so it will be different in each case (but the idea is the same):
  3. src/handlers/file.js: src folder contains the code for the application's Lambda Function.
  4. __tests__/unit/handlers/file.test.js: test folder contains the unit tests for the application code.
  5. package.json: This file of NodeJS contains the application dependencies and is used for the sam build. If you are using Python language instead of NodeJS, the file will be requirements.txt.

AWS SAM template anatomy

This is the structure of the template.yaml.

# The AWSTemplateFormatVersion identifies the capabilities of the template
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/format-version-structure.html
AWSTemplateFormatVersion: '2010-09-09'
# Optional: description
Description: >-
  Any text here.
  Multi-line

# Transform section specifies one or more macros that AWS CloudFormation uses to process your template
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-section-structure.html
Transform: AWS::Serverless-2016-10-31  

# Optional: Globals section defines properties that are common to all your serverless functions and APIs
Globals:
  Function:
    Timeout: 3
    MemorySize: 128
    Tracing: Active
    Tags:
      iac: SAM

# Optional: provides additional information about the template
Metadata:
  template metadata

# Optional: Values to pass to your template at runtime (when you create or update a stack).
Parameters:
  set of parameters

# Optioal: A mapping of keys and associated values that you can use to specify conditional parameter values, similar to a lookup table
Mappings:
  set of mappings

# Optional: conditions that control whether certain resources are created or whether certain resource properties are assigned a value during stack creation or update
Conditions:
  set of conditions

# Resources declares the AWS resources that you want to include in the stack.
# Resources section can contain a combination of AWS CloudFormation resources and AWS SAM resources
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html
Resources:
  set of resources

# Optional: The values that are returned whenever you view your stack's properties
Outputs:
  set of outputs
Enter fullscreen mode Exit fullscreen mode

More information here.

Prerequisites

Example of SAM application

Let's start reviewing one example of the SAM application to show some options about what we can do here.

I will show you the part of the template.yaml file which affects the specific service.

It's important to remember that you can incorporate CloudFormation resources into our SAM template. However, AWS SAM offers specific resources that are specially tailored for creating Lambda Functions, API Gateway, AppSync, DynamoDB, Step Functions, among several other services. All the relevant information can be found here.

Example of Lambda Function

The first special type, and more important, is the AWS::Serverless::Function, which you should use to create Lambda Functions (more information here).

Resources:
  # Each Lambda function is defined by properties:
  # https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction

  # This is a Lambda function config associated with the source code: hello-from-lambda.js
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: src/handlers/hello-from-lambda.helloFromLambdaHandler
      Runtime: nodejs14.x
      Architectures:
        - x86_64
      MemorySize: 128
      Timeout: 100
      Description: A Lambda function that returns a static string.
      Policies:
        # Give Lambda basic execution Permission to the helloFromLambda
        - AWSLambdaBasicExecutionRole
Enter fullscreen mode Exit fullscreen mode

Adding an API Gateway

To add the API Gateway resource you can use the specific type of AWS::Serverless::Api (more information here).

Resources:
  ...
  BasicAWSApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      Name: Basic AWS Api Gateway resource
      StageName: poc
      ...
Enter fullscreen mode Exit fullscreen mode

You can also add a trigger in the Lambda Function updating the section Events:

Resources:
  HelloWorldFunction:
    Properties:
      ...
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /
            Method: get
Enter fullscreen mode Exit fullscreen mode

And you should create in events folder the json definition of the method:

{
    "httpMethod": "GET"
}
Enter fullscreen mode Exit fullscreen mode

Adding an scheduled event to the Lambda Function

Including a scheduled event to the Lambda Function is quite similar to adding an API.

Resources:
  HelloWorldFunction:
    Properties:
      ...
      Events:
        CloudWatchEvent:
          Type: Schedule
          Properties:
            Schedule: cron(0 * * * ? *)
Enter fullscreen mode Exit fullscreen mode

And you should create in events folder the json definition of the rule:

{
  "id": "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c",
  "detail-type": "Scheduled Event",
  "source": "aws.events",
  "account": "",
  "time": "1970-01-01T00:00:00Z",
  "region": "us-west-2",
  "resources": [
    "arn:aws:events:us-west-2:xxxxxxxxxxxx:rule/ExampleRule"
  ],
  "detail": {}
}
Enter fullscreen mode Exit fullscreen mode

Adding the SNS topic resource

In this case, I will include the Lambda Function as a subscriber of my SNS topic.

Resources:
  ...
  SnsTopicAsTriggerOfLambdaFunction:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: !Sub '${ResourcesName}'
      DisplayName : Topic used for trigger the lambda function
      Subscription:
        - Protocol: lambda
          Endpoint: !GetAtt HelloWorldFunction.Arn
      TracingConfig: Active
Enter fullscreen mode Exit fullscreen mode

Saving one property in the SSM Parameter Store

Resources:
  ...
  MySnsTopicArnParameter:
      Type: AWS::SSM::Parameter
      Properties:
        Name: /general/sns/topic-test
        Type: String
        Value: !Ref SnsTopicAsTriggerOfLambdaFunction
Enter fullscreen mode Exit fullscreen mode

More examples

As you can see, you can add any resource using the usual CloudFormation code inside the template.yaml file.

I recommend that you run aws sam init and try to create different projects from the templates.

Top comments (1)

Collapse
 
rdarrylr profile image
Darryl Ruggles

SAM is great! Thanks for your work on this fine article.