Building larger serverless applications can be tricky - creating many lambda functions as well as other resources such as DynamoDB tables, S3 buckets, API Gateways takes quite a lot of time if we were to do it manually from AWS Console. Not to mention other problems such as redeploying the app to a different region, reviewing the infrastructure etc.
AWS Serverless Application Model (AWS SAM for short) simplifies a lot of those issues.
Built with with best practices in mind it allows you to:
- define your infrastructure as code using a YAML template (which can go through code review!)
- define resources such as lambda functions, DynamoDB tables etc. in a much simpler way than doing it directly in CloudFormation (which SAM is built on top of)
- build and deploy a serverless application from a command line
- debug and test lambda functions locally using SAM CLI
- debug and test lambda functions from WITHIN your editor with AWS Toolkit extension
The aim of SAM is to allow developers to build products using the AWS infrastructure with only a few lines of code.
It is built on top of AWS CloudFormation but is much less verbose.
You describe your infrastructure as code in YAML and this allows you to spin up services in a much more straightforward way than through Cloudformation
The
sam
CLI is really powerful. It allows to you to build, deploy and locally invoke your functions. Amazingly helpful in development.Tomasz recommends installing the AWS Toolkit in your code editor of choice.
- Among other things, this allows your to debug your functions locally.
Install:
Init a project:
sam init
Build project:
Cd to the project then do:
sam build
Deploy:
sam deploy --guided
It will ask few questions for first time deploy:
Stack Name: sam-example-app
AWS Region: eu-central-1
All 'Yes' for the rest of questions
After successfully deploy, we can get our API getway URL, which we can call:
curl https://xxxx.execute-api.eu-central-1.amazonaws.com/Prod/hello/
It will return:
{"message":"hello world"}
This is defined in app.js file.
Run locally lambda function:
sam local invoke
or
You can use AWS Toolkit in VSCode to run locally as well.
Trigger an event locally:
create new files under events/simple.json
{ "body": "{\"message\": \"hello world\"}" }
Run:
sam local invoke --event events/simple.json
Output: // INFO event { body: '{"message": "hello world"}' }
there is a default event.json file we can use to test:
sam local invoke --event events/event.json
AWS SAM allows us to deploy entire serverless applications to AWS with only a couple of lines of code in a YAML template.
But then again, how do we know what was deployed where? How can I find my lambda functions?
In this lesson we're going to learn how to review the AWS SAM stack deployment in AWS Console - taking a look at reviewing the stack, checking out the lambda function (and seeing what kind of things SAM is configuring for us) as well as digging into CloudFormation stack (which SAM is built on top of).
Once we've deployed our function, we can check on the console that all is as we'd expect.
Console > Lambda > Applications we can review:
- The endpoint
- The resources
- Monitoring - this allows us to see the relevant CloudWatch metrics without having to navigate around the (clunky) UI
Clicking on the lambda resource we can review:
- The function code
- Tags (that are created by SAM)
- Role
- Basic settings (including timeout)
Global values in the template.yaml can be set for all resources deployed by SAM.
- SAM is deployed using CloudFormation, so looking over there we can review:
- All the events
- All of the resources
Deploy an S3 bucket and trigger an AWS Lambda function:
- In the template.yaml file, we're going to add additional resources. The spacing here is what tells SAM what level everything is on so the spacing should match the
HelloWorldFunction
above it.
Resources:
HelloWorldFunction:
..
..
MyFilesBucket:
Type: AWS::S3::Bucket
We can run sam build
and sam deploy
to create the bucket.
sam build
sam deploy
Then we can check console, whether S3 bucket was created or not.
Back to template.yaml file, update:
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: app.lambdaHandler Runtime: nodejs12.x Events: HelloWorld: 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 FileUpload: Type: S3 Properties: Bucket: !Ref MyFilesBucket Events: s3:ObjectCreated:* MyFilesBucket: Type: AWS::S3::Bucket
We can then update our function to log out the s3 event.
console.log(event.Records[0].s3);
Now, we build and deploy (sam build
and sam deploy
).
You can upload a file to the bucket and then check the log stream. It should have triggered the lambda function.
Deploy a DynamoDB to AWS:
MyAwesomeTable:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: id
Type: String
TableName: my-awesome-database