This is the second article of a serie about AWS SAM. The next will be one related with the deployment.
To keep it simple, we will create a SAM application from a quick start template
using the standalone function
. However you could try a different template, the steps to follow should be the same.
The code example is available in
GitHub
repository here. If you want to see the step by step you can check the commit history, where you can find the evolution of the application through the steps explained in the following lines.
These are all the steps that I want to show you in this article:
- Step 1: Create a SAM application
- Step 2 (Optional): Test your application locally
- Step 3 (Optional): Unit test
- Step 4: Build your application
- Step 5: Deploy manually your application with the CLI
- Step 6 (Optional): AWS SAM Accelerate (Preview) - Sync
Step 1: Create a sample SAM application
The first step is to create our application through a quick start template: Standalone function
.
To create a new application from a template we run the sam init
command.
> sam init
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: > 1
Choose an AWS Quick Start application template
1 - Hello World Example
2 - Data processing
3 - Hello World Example with Powertools for AWS Lambda
4 - Multi-step workflow
5 - Scheduled task
6 - Standalone function
7 - Serverless API
8 - Infrastructure event management
9 - Lambda Response Streaming
10 - Serverless Connector Hello World Example
11 - Multi-step workflow with Connectors
12 - GraphQLApi Hello World Example
13 - Full Stack
14 - Lambda EFS example
15 - Hello World Example With Powertools for AWS Lambda
16 - DynamoDB Example
17 - Machine Learning
Template: > 6
Which runtime would you like to use?
1 - dotnet6
2 - nodejs20.x
3 - nodejs18.x
4 - nodejs16.x
Runtime: > 2
Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.
Based on your selections, the only dependency manager available is npm.
We will proceed copying the template using npm.
Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: > N
Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: > N
Would you like to set Structured Logging in JSON format on your Lambda functions? [y/N]:
Project name [sam-app]: > sam-app
-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: nodejs20.x
Architectures: x86_64
Dependency Manager: npm
Application Template: quick-start-from-scratch
Output Directory: .
Configuration file: sam-app/samconfig.toml
Next steps can be found in the README file at sam-app/README.md
Commands you can use next
=========================
[*] Create pipeline: cd sam-app && sam pipeline init --bootstrap
[*] Validate SAM template: cd sam-app && sam validate
[*] Test Function in the Cl
At the end of the command line messages appears
Commands you can use next
, where other SAM CLI commands are suggested as the next steps to execute.
This is the basic application that has been created (only with one lambda function for easy understanding):
Note that we have 4 of the 5 files that we reviewed before:
- src/handlers/hello-from-lambda.js
- _test_/unit/handlers/hello-from-lambda.test.js
- template.yaml
- package.json
We don't have the folder events
because we only create one simple Lambda Function with no event integrations
Step 2 (Optional): Test your application locally
The AWS SAM CLI provides the sam local
command to run your application using Docker containers that simulate the execution environment of Lambda.
Invoke your Lambda function running sam local invoke
:
> sam local invoke
Invoking src/handlers/hello-from-lambda.helloFromLambdaHandler (nodejs20.x)
Local image was not found.
Removing rapid images for repo public.ecr.aws/sam/emulation-nodejs20.x
Building image.............................................................................................................................................................................................................................................................................
Using local image: public.ecr.aws/lambda/nodejs:20-rapid-x86_64.
Mounting /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app as /var/task:ro,delegated, inside
runtime container
START RequestId: ba22ff8c-02f8-42a7-980d-0f0248ee63bf Version: $LATEST
2024-01-22T22:11:35.245Z ae4b9347-e347-4ec0-a7a1-f34a3533ec8b INFO Hello from Lambda!
END RequestId: ae4b9347-e347-4ec0-a7a1-f34a3533ec8b
REPORT RequestId: ae4b9347-e347-4ec0-a7a1-f34a3533ec8b Init Duration: 0.06 ms Duration: 181.07 ms Billed Duration: 182 ms Memory Size: 128 MB Max Memory Used: 128 MB
"Hello from Lambda!"
We received the response "Hello from Lambda!" and more useful information (Duration, Billed Duration, Memory Size, or Max Memory Used).
If you have more than one Lambda Function, you must add the name which appears in the template.yaml
file.
sam local invoke "helloFromLambdaFunction"
Invoking src/handlers/hello-from-lambda.helloFromLambdaHandler (nodejs20.x)
Local image is up-to-date
Using local image: public.ecr.aws/lambda/nodejs:20-rapid-x86_64.
Mounting /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app as /var/task:ro,delegated, inside
runtime container
START RequestId: 323bbea4-2d41-407d-97b6-8605cbe454c3 Version: $LATEST
2024-01-22T22:20:25.541Z 9fadbf3c-0c9f-4728-b1a7-4ab96e715172 INFO Hello from Lambda!
END RequestId: 9fadbf3c-0c9f-4728-b1a7-4ab96e715172
REPORT RequestId: 9fadbf3c-0c9f-4728-b1a7-4ab96e715172 Init Duration: 0.05 ms Duration: 142.91 ms Billed Duration: 143 ms Memory Size: 128 MB Max Memory Used: 128 MB
"Hello from Lambda!"
You also can test an API locally if your SAM project includes it.
You should run
sam local start-api
command, which starts up a local endpoint that replicates your REST API endpoint.
Step 3 (Optional): Unit test
Tests are defined in the _tests_ folder in this project. Use npm to install the Jest test framework and run unit tests.
npm install
...
npm run test
> replaced-by-user-input@0.0.1 test
> node --experimental-vm-modules node_modules/jest/bin/jest.js
console.info
Hello from Lambda!
at helloFromLambdaHandler (src/handlers/hello-from-lambda.mjs:9:13)
(node:31412) ExperimentalWarning: VM Modules is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
PASS __tests__/unit/handlers/hello-from-lambda.test.mjs
Test for hello-from-lambda
✓ Verifies successful response (30 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.553 s
Ran all test suites.
Step 4: Build your application
The sam build
command builds any dependencies that your application has, and copies your application source code to folders under .aws-sam/build
to be zipped and uploaded to Lambda.
> sam build
Starting Build use cache
Manifest file is changed (new hash: 57574ed173cdc6a98b283bd7b00b44ca) or dependency folder
(.aws-sam/deps/ee51225c-b9b8-433f-ab8b-3821871f820a) is missing for (helloFromLambdaFunction), downloading
dependencies and copying/building source
Building codeuri: /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app runtime: nodejs20.x metadata:
{} architecture: x86_64 functions: helloFromLambdaFunction
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrcAndLockfile
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUp
Running NodejsNpmBuilder:CopyDependencies
Running NodejsNpmBuilder:CleanUpNpmrc
Running NodejsNpmBuilder:LockfileCleanUp
Running NodejsNpmBuilder:LockfileCleanUp
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
These are the new files of our SAM project:
Step 5: Deploy manually your application with the CLI
Now we want to deploy our application and We will do it manually using the CLI, although in this other article. I will explain how to do it with a pipeline (automatically).
Remember that AWS SAM uses AWS CloudFormation as the underlying deployment mechanism.
As we don't have a configuration file containing all the values, we are going to create one. We run the sam deploy -- guided
command which will search as a first step if a samconfig.toml file exists and if not the AWS SAM CLI will ask us about the necessary information to deploy our application.
The
sam deploy
command will package and upload the application artifacts to the S3 bucket, and deploys the application using AWS CloudFormation
> sam deploy --guided
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Found
Reading default arguments : Success
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]:
AWS Region [eu-west-1]:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [Y/n]:
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]:
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]:
Save arguments to configuration file [Y/n]:
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
Looking for resources needed for deployment:
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False
Parameter "stack_name=sam-app" in [default.deploy.parameters] is defined as a global parameter
[default.global.parameters].
This parameter will be only saved under [default.global.parameters] in
/Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app/samconfig.toml.
Saved arguments to config file
Running 'sam deploy' for future deployments will use the parameters saved above.
The above parameters can be changed by modifying samconfig.toml
Learn more about samconfig.toml syntax at
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
Uploading to sam-app/c20f3d4923fb213486783dd25f269a52 38478 / 38478 (100.00%)
Deploying with following values
===============================
Stack name : sam-app
Region : eu-west-1
Confirm changeset : True
Disable rollback : False
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
Uploading to sam-app/3752a1ab023524618cd64cc55081484c.template 734 / 734 (100.00%)
Waiting for changeset to be created..
CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------
Operation LogicalResourceId ResourceType Replacement
-------------------------------------------------------------------------------------------------------------
+ Add helloFromLambdaFunctionRo AWS::IAM::Role N/A
le
+ Add helloFromLambdaFunction AWS::Lambda::Function N/A
-------------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:eu-west-1:000000000000:changeSet/samcli-deploy1705962828/ee61a1a2-9083-4029-9ee1-126661b04541
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2024-01-22 23:34:17 - Waiting for stack create/update to complete
CloudFormation events from stack operations (refresh every 5.0 seconds)
-------------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
-------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS AWS::CloudFormation::Stac sam-app User Initiated
k
CREATE_IN_PROGRESS AWS::IAM::Role helloFromLambdaFunctionRo -
le
CREATE_IN_PROGRESS AWS::IAM::Role helloFromLambdaFunctionRo Resource creation
le Initiated
CREATE_COMPLETE AWS::IAM::Role helloFromLambdaFunctionRo -
le
CREATE_IN_PROGRESS AWS::Lambda::Function helloFromLambdaFunction -
CREATE_IN_PROGRESS AWS::Lambda::Function helloFromLambdaFunction Resource creation
Initiated
CREATE_COMPLETE AWS::Lambda::Function helloFromLambdaFunction -
CREATE_COMPLETE AWS::CloudFormation::Stac sam-app -
k
-------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - sam-app in eu-west-1
Remember that the executed command will create the samconfig.toml
file in our project to save the deployment configuration and be able to repeat it without configuration.
From now on, to deploy our SAM project we just need to run the sam deploy
command, so we run it but if we have no changes, the deployment will fail:
> sam deploy
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
A different default S3 bucket can be set in samconfig.toml
Or by specifying --s3-bucket explicitly.
File with same data already exists at sam-app/c20f3d4923fb213486783dd25f269a52, skipping upload
Deploying with following values
===============================
Stack name : sam-app
Region : eu-west-1
Confirm changeset : True
Disable rollback : False
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
File with same data already exists at sam-app/3752a1ab023524618cd64cc55081484c.template, skipping upload
Waiting for changeset to be created..
Error: No changes to deploy. Stack sam-app is up to date
Step 6 (Optional): AWS SAM Sync
We already have deployed our application in the cloud and you may want to synchronize the changes, i.e. deploy the changes in real-time when we save the changes
(without running the deploy command).
The
sam sync
command syncs your local application changes to the AWS Cloud. Use sync to build, package, and deploy changes to your development environment as you iterate on your application. As a best practice, run sam sync after you finish iterating on your application to sync changes to your AWS CloudFormation stack.Be careful if you use this functionality.
First
it is in preview
and also as you will see in the next lines in the console: "The SAM CLI will use the AWS Lambda, Amazon API Gateway, and AWS StepFunctions APIs toupload your code without performing a CloudFormation deployment. This will cause drift in your CloudFormation stack
."The sync command should only be used against a development stack.
> sam sync --stack-name sam-app --watch
The SAM CLI will use the AWS Lambda, Amazon API Gateway, and AWS StepFunctions APIs to upload your code without
performing a CloudFormation deployment. This will cause drift in your CloudFormation stack.
**The sync command should only be used against a development stack**.
Confirm that you are synchronizing a development stack.
Enter Y to proceed with the command, or enter N to cancel:
[Y/n]:
Queued infra sync. Waiting for in progress code syncs to complete...
Starting infra sync.
Manifest is not changed for (helloFromLambdaFunction), running incremental build
Building codeuri: /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app runtime: nodejs20.x
metadata: {} architecture: x86_64 functions: helloFromLambdaFunction
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrcAndLockfile
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:CleanUpNpmrc
Running NodejsNpmBuilder:LockfileCleanUp
Running NodejsNpmBuilder:LockfileCleanUp
Build Succeeded
Successfully packaged artifacts and wrote output template to file /var/folders/wq/bz6xngtx5h3f5gf8py3kf28c0000gn/T/tmppcg60qga.
Execute the following command to deploy the packaged template
sam deploy --template-file /var/folders/wq/bz6xngtx5h3f5gf8py3kf28c0000gn/T/tmppcg60qga --stack-name <YOUR STACK NAME>
Deploying with following values
===============================
Stack name : sam-app
Region : eu-west-1
Disable rollback : False
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
Capabilities : ["CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"]
Parameter overrides : {}
Signing Profiles : null
Initiating deployment
=====================
2024-01-22 23:43:31 - Waiting for stack create/update to complete
CloudFormation events from stack operations (refresh every 0.5 seconds)
---------------------------------------------------------------------------------------------------------
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
---------------------------------------------------------------------------------------------------------
UPDATE_IN_PROGRESS AWS::CloudFormation::Sta sam-app User Initiated
ck
UPDATE_IN_PROGRESS AWS::CloudFormation::Sta sam-app Transformation succeeded
ck
CREATE_IN_PROGRESS AWS::CloudFormation::Sta AwsSamAutoDependencyLaye -
ck rNestedStack
CREATE_IN_PROGRESS AWS::CloudFormation::Sta AwsSamAutoDependencyLaye Resource creation
ck rNestedStack Initiated
CREATE_COMPLETE AWS::CloudFormation::Sta AwsSamAutoDependencyLaye -
ck rNestedStack
UPDATE_IN_PROGRESS AWS::Lambda::Function helloFromLambdaFunction -
UPDATE_COMPLETE AWS::Lambda::Function helloFromLambdaFunction -
UPDATE_COMPLETE_CLEANUP_ AWS::CloudFormation::Sta sam-app -
IN_PROGRESS ck
UPDATE_COMPLETE AWS::CloudFormation::Sta sam-app -
ck
---------------------------------------------------------------------------------------------------------
Stack update succeeded. Sync infra completed.
Infra sync completed.
The console still listens for changes and if we change our lambda code and save it:
The console will be updated automatically as follow:
Syncing Lambda Function helloFromLambdaFunction...
Manifest is not changed for (helloFromLambdaFunction), running incremental build
Building codeuri: /Users/alazaroc/Documents/MyProjects/github/aws/sam/sam-app runtime: nodejs20.x
metadata: {} architecture: x86_64 functions: helloFromLambdaFunction
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrcAndLockfile
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:CleanUpNpmrc
Running NodejsNpmBuilder:LockfileCleanUp
Running NodejsNpmBuilder:LockfileCleanUp
Finished syncing Lambda Function helloFromLambdaFunction.
When you stop it (control + C
) in the console it will appear:
^CShutting down sync watch...
Sync watch stopped.
When you executed the sync command, a nested stack associated with your main stack (sam-app) was created:
And when the console stops being synchronized, this nested stack is NOT deleted.
How to remove the nested stack created with the sync command?
You have to run the sam deploy
command again and it will be removed:
> sam deploy
Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
A different default S3 bucket can be set in samconfig.toml
Or by specifying --s3-bucket explicitly.
File with same data already exists at sam-app/c20f3d4923fb213486783dd25f269a52, skipping upload
Deploying with following values
===============================
Stack name : sam-app
Region : eu-west-1
Confirm changeset : True
Disable rollback : False
Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-k2z3x0eqvuxq
Capabilities : ["CAPABILITY_IAM"]
Parameter overrides : {}
Signing Profiles : {}
Initiating deployment
=====================
File with same data already exists at sam-app/3752a1ab023524618cd64cc55081484c.template, skipping upload
Waiting for changeset to be created..
CloudFormation stack changeset
Operation LogicalResourceId ResourceType Replacement
- Modify helloFromLambdaFunction AWS::Lambda::Function False
- Delete AwsSamAutoDependencyLaye AWS::CloudFormation::Sta N/A
rNestedStack ck
---------------------------------------------------------------------------------------------------------
Changeset created successfully. arn:aws:cloudformation:eu-west-1:000000000000:changeSet/samcli-deploy1705963790/6b5464b9-0b8e-44c2-93c0-8e0f509c9110
Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y
2024-01-22 23:50:02 - Waiting for stack create/update to complete
CloudFormation events from stack operations (refresh every 5.0 seconds)
ResourceStatus ResourceType LogicalResourceId ResourceStatusReason
UPDATE_IN_PROGRESS AWS::CloudFormation::Sta sam-app User Initiated
ck
UPDATE_IN_PROGRESS AWS::Lambda::Function helloFromLambdaFunction -
UPDATE_COMPLETE AWS::Lambda::Function helloFromLambdaFunction -
UPDATE_COMPLETE_CLEANUP_ AWS::CloudFormation::Sta sam-app -
IN_PROGRESS ck
DELETE_IN_PROGRESS AWS::CloudFormation::Sta AwsSamAutoDependencyLaye -
ck rNestedStack
DELETE_COMPLETE AWS::CloudFormation::Sta AwsSamAutoDependencyLaye -
ck rNestedStack
UPDATE_COMPLETE AWS::CloudFormation::Sta sam-app -
ck
Successfully created/updated stack - sam-app in eu-west-1
Step 7: Clean up
If you are followed this tutorial you will only have one stack in our AWS Account, so you can run the sam delete
command (which deletes the main stack: sam-app).
> sam delete
Are you sure you want to delete the stack sam-app in the region eu-west-1 ? [y/N]: y
Are you sure you want to delete the folder sam-app in S3 which contains the artifacts? [y/N]: y
- Deleting S3 object with key sam-app/c20f3d4923fb213486783dd25f269a52
- Deleting S3 object with key sam-app/3752a1ab023524618cd64cc55081484c.template
- Deleting Cloudformation stack sam-app
Deleted successfully
Next steps
- If you need more information about SAM I recommend you to visit the AWS documentation here
- Next post: How to add CI/CD to my SAM project
- Comment this post
Top comments (0)