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)
- With the
-
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:
- template.yaml: This file contains the AWS SAM template that defines your application's AWS resources.
-
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):
- Depends on the programming language (in this case
-
src/handlers/file.js:
src
folder contains the code for the application's Lambda Function. -
__tests__/unit/handlers/file.test.js:
test
folder contains the unit tests for the application code. -
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
More information here.
Prerequisites
- AWS CLI
- AWS SAM CLI (here)
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
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
...
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
And you should create in events
folder the json
definition of the method:
{
"httpMethod": "GET"
}
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 * * * ? *)
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": {}
}
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
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
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)
SAM is great! Thanks for your work on this fine article.