SAM CLI CheatSheet

Fabio Gollinucci
10 min readMar 10, 2023

--

The AWS Serverless Application Model (AWS SAM) is an open-source framework that you can use to build serverless applications on AWS. It is an extension of CloudFormation, you get the reliable deployment capabilities of AWS CloudFormation. You can define resources by using AWS CloudFormation in your AWS SAM template.

Authentication takes place exactly as for the AWS CLI, the same profiles described in .aws/credentials or environment variables will be used. Read more about this at AWS CLI configurations and credentials.

Commands documentation can be found at official SAM AWS documentation.

Initialize project

A SAM project require just a template file, in YAML ( template.yml or template.yaml) or JSON ( template.json) format. Optionally a samconfig.toml can be found with SAM CLI's configurations; this file is not required by SAM CLI.

Application templates

A SAM project can be bootstrapped from a list of AWS managed templates:

sam init --runtime nodejs16.x

an interactive setup will be prompt asking for template information:

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 - Hello World Example With Powertools
3 - Multi-step workflow
4 - Standalone function
5 - Scheduled task
6 - Data processing
7 - Serverless API
8 - Serverless Connector Hello World Example
9 - Multi-step workflow with Connectors
Template: 1

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.

Select your starter template
1 - Hello World Example
2 - Hello World Example TypeScript
Template: 1

Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: N

The init command can be forged with template name and parameter's value as command's arguments:

sam init --runtime nodejs16.x --app-template hello-world --name sam-app

The list of available templates can be found at aws/aws-sam-cli-app-templates.

After the init command the SAM application will be found in a new directory named as "name" parameter:

.
└── sam-app
├── events
│ └── event.json
├── hello-world
│ ├── app.js
│ ├── package.json
│ └── tests
│ └── unit
│ └── test-handler.js
├── README.md
├── samconfig.toml
└── template.yaml

Custom application templates

SAM templates are based on Cookiecutter, it’s possible to create your own template.

The template directory names and filenames can be “templated”:

{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.js

A cookiecutter.json configuration file is required:

{
"project_name": "Name of the project",
"runtime": "nodejs16.x",
"architectures": {
"value": []
},
"_copy_without_render": [
".gitignore"
]
}

Templates can be retrieved from GitHub:

sam init --location gh:aws-samples/cookiecutter-aws-sam-python

from a local Zip file:

sam init --location /path/to/template.zip

from a remote Zip file:

sam init --location https://example.com/path/to/template.zip

or from a directory:

sam init --location /path/to/template/folder

Template file

The SAM template file ( template.yaml, template.yml or template.json) need to be present in the root project folder:

.
└── template.yaml

The template file contains the format version, used transformers and resources to deploy:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
# here resources list

For resources declaration follow the CloudFormation documentation.

Configuration file

The SAM CLI configuration file samconfig.toml contains the default configurations for SAM command's arguments in TOML format. This file shouldn't be manually changed, it should be managed by CLI deploys executed with --guided parameter. This file is not required

The configuration file start with version declaration, then is divided in “sections”:

version = 0.1

[default]
#...

[dev]
#...

[prod]
#...

Every sections contains the SAM command parameters specifications:

version = 0.1

[default]
[default.deploy]
[default.deploy.parameters]
#...

[dev]
[dev.deploy]
[dev.deploy.parameters]
#...

This refers to SAM CLI command “deploy”.

Also other commands like “invoke” can have configurations specified in this way:

version = 0.1

[dev.local_invoke]
[dev.local_invoke.parameters]
#...

The - in the command name will become _ in configuration file.

version = 0.1

[dev]
[dev.deploy]
[dev.deploy.parameters]
stack_name = "sam-app-dev"
region = "eu-west-1"
profile = "example"

As command name, the - in the command parameter name will become _ in configuration file.

Every SAM CLI commands have --config-env parameter, if not specified the "default" one is used. Executing a deploy with "dev" configuration env:

sam deploy --config-env dev

will result in a execution like:

sam deploy --stack-name example-dev --region eu-west-1 --profile example

Local Lambda testing

Lambda functions can be invoke locally using the SAM CLI local invoke command passing the resource's template key:

sam local invoke ExampleFunction

By design the execution will be performed inside a Docker container with the correct runtime corresponding image.

The local execution will be performed using local AWS profile configured:

sam local invoke --profile example ExampleFunction

Pay attention in case of differences between the user who is debugging and the role of the Lambda that will be deployed, they have different policies.

The function execution can be configured using environment variables from a JSON file:

sam local invoke --env-vars env.json ExampleFunction

The function execution event can be loaded from a JSON file too:

sam local invoke --event event.json ExampleFunction

The debugger can be attach specifying a debug port:

sam local invoke --debug-port 5858 ExampleFunction

Stack resources build

If the template include Lambda Functions that require dependencies or code build, before the deploy you need to build the project:

sam build

This command will use the default build configurations for functions’s runtime specified and produce a built template into .sam directory:

.
├── .aws-sam
│ ├── build
│ │ └── template.yaml
│ └── build.toml
└── template.yaml

At this point, subsequent deploy command executions will deploy .aws-sam/build/template.yaml template file, changes to ./template.yaml file will not be deployed (unless you run build command again).

The application build can be performed into a Docker container:

sam build --use-container

This removes the need to have the lambda runtime available in the local machine.

Stack deploy

When the SAM template is ready for the first deploy execute the deploy command with a --guided parameter:

sam deploy --guided

The AWS credential profile is not asked during guided wizard, so add the --profile to the first deploy:

sam deploy --profile personal --guided

During the deploy the following action will be executed:

  • It will check if the stack aws-sam-cli-managed-default exists in the account and region selected.
  • If not present, the stack aws-sam-cli-managed-default will be deployed (creating the deploy bucket aws-sam-cli-managed-default-).
  • The template file and code artifacts will be uploaded to deploy bucket aws-sam-cli-managed-default-.
  • A CloudFormation change set will be created elaborating differences to deploy.
  • If the change set will be approved (manually or automatically using --no-confirm-changeset command parameter) the stack update start.

At the end of deploy a samconfig.toml file will be generated next to the template file:

.
├── samconfig.toml
└── template.yaml

Stack parameters

When a template declare parameters with a “Default” attribute set:

Parameters:
Project:
Type: String
Default: "example"

the value will be proposed during deploy with --guided and automatically valorized for the first deploy.

When a template declare parameters without a “Default”:

Parameters:
Project:
Type: String
Default: "example"

it will thread as required, the value need to be set to proceed with guided deploy or fail if not set in other way.

The parameters can be specified from deploy arguments:

sam deploy --parameter-overrides Project=example

Multiple parameters need to space separated:

sam deploy --parameter-overrides Project=example Environment=test ...

Also the samconfig.toml can specify parameters overrides in its sections:

[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "example"
region = "eu-west-1"
profile = "example"
capabilities = "CAPABILITY_IAM CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND"
image_repositories = []
disable_rollback = false
parameter_overrides = "ProjectName=\"example\""

When a template declare parameters with a “NoEcho” attribute set:

Parameters:
Password:
Type: String
NoEcho: true

it will thread as secrets, the value will be not written into samconfig.toml and cannot be retrieve from deployed CloudFormation stack. Parameters value's reference, like Lambda function's environment variables, can be displayed clearly. Pay attention to where the value is used, rather prefer SSM parameters or Secrets Managers.

Parameter specified with “parameter-overrides” settings will be set for the current deploy and saved by CloudFormation into its state. Subsequent deploy that does not specify parameters overrides values will use the previous deploy’s parameter value.

Multiple stack deploy

When the project gets big there might be a need to split it into separate stacks.

Different template files can be deploy individually specifying the template file path:

sam deploy --template-file database/template.yaml
sam deploy --template-file events/template.yaml
sam deploy --template-file api/backoffice/template.yaml
sam deploy --template-file api/frontend/template.yaml

A template file can be referenced from an other template as AWS::Serverless::Application resource:

Resources:

database:
Type: AWS::Serverless::Application
Properties:
Location: database/template.yaml
Parameters:
ProjectName: !Ref ProjectName
EnvironmentName: !Ref EnvironmentName

events:
Type: AWS::Serverless::Application
Properties:
Location: events/template.yaml
Parameters:
ProjectName: !Ref ProjectName
EnvironmentName: !Ref EnvironmentName

When templates are described in this way, they are called “nested application”. When templates are deployed as nested application they can no longer be deployed individually, you will need to delete and recreate them.

Stack update

Changes to the application will be made through changes to the template itself, manual editing resources via the AWS CLI or web console is considered a best practice. CloudFormation stacks deploy the described resources and when a change is request, with a subsequent deploy, will apply these changes assuming the state of the resource is the same as applied to the previous deployment. A check of the current state of the resource will not be performed to evaluate its changes, with the Infrastructure as Code (IaC) approach it is the code that is the primary source of truth, not the resource state itself.

In order to deploy an infrastructure configuration change, modify the template file and run the deploy command again. Pay attention to build command usage, if the application code require a build step execute the build command before every deploy execution.

Stack deletion

Deleting a stack is an important step in SAM applications; allows you to try multiple solutions and not have to deal with failed trials. This is also a mandatory step for “CREATE_FAILED” stacks.

Delete stack with delete SAM command:

sam delete

specify the config env name if you want to delete a specific stack:

sam delete --config-env dev

The SAM CLI will ask for a confirmation before executing the stack delete.

Deletion policy

Not every AWS resources cn be easily deleted, for example S3 bucket cannot be deleted if there are some file objects inside. The resource delete behaviour can be configured with DeletionPolicy attribute:

Resources:
MyBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain

The deletion policy can be:

  • Delete: CloudFormation deletes the resource and all its content if applicable during stack deletion.
  • Retain: CloudFormation keeps the resource without deleting the resource or its contents when its stack is deleted.
  • Snapshot: For resources that support snapshots, CloudFormation creates a snapshot for the resource before deleting it.

Pay attention to the names of the resources that are left, a subsequent deployment could fail trying to create a resource with the same name. For example an S3 bucket cannot be created with the same name of an existing one.

Stack statuses

During deploy, update, delete, import operations the stack will assume different statuses.

REVIEW_IN_PROGRESS

A stack changeset has been created by SAM and is pending approval.

CREATE_IN_PROGRESS, UPDATE_IN_PROGRESS, DELETE_IN_PROGRESS

Stack resources are being created, modified or deleted by CloudFormation.

CREATE_COMPLETE, UPDATE_COMPLETE, DELETE_COMPLETE

Stack resources were successfully created, modified or deleted by CloudFormation.

UPDATE_COMPLETE_CLEANUP_IN_PROGRESS, UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS

Stack resources replaced by a modification that require a re-creation are going to be deleted.

CREATE_FAILED

The first stack deploy fail. The stack cannot perform a rollback (there are no previous template states) and need to be deleted before starting a new deploy.

UPDATE_FAILED, DELETE_FAILED

Stack resources fail to create, modify or delete by CloudFormation. Now the stack will be perform an automatic rollback, unless the --disable-rollback parameter is set to deploy command.

ROLLBACK_IN_PROGRESS

Stack resources will be modified returning the template state to the last successful one (CREATE_COMPLETE, UPDATE_COMPLETE).

UPDATE_ROLLBACK_FAILED, ROLLBACK_FAILED

The automatic rollback fail, resources are now in a inconsistent state and need to be fixed manually. The stack cannot be update, you can continue the rollback procedure (after the appropriate fixes) or you will need to delete the stack and recreate it.

Version control considerations

Do not put under version control the .aws-sam directory, it contains the builded version of the template with Lambda functions built with its dependencies installed. Build the deploy before every deploy, if you are using this deploy approach.

Since the samconfig.toml can contains parameters overrides value, if it is under version control every deploy from local machine will override parameters with these values. If the stack parameters was change from the AWS CLI or web console the parameters value will be overwritten.

Here an example of .gitignore file:

.aws-sam
samconfig.toml

Pipeline

Where possible always use a pipeline to build and deploy your serverless application.

The application build can be performed into a Docker container:

sam build --use-container

This removes the need to have the lambda runtime available in the pipeline step.

Use the appropriate SAM CLI deploy commands in order to skip changeset confirmation and do not fail if template has no changes to deploy:

sam deploy --resolve-s3 --no-confirm-changeset --no-fail-on-empty-changeset

AWS provide a Docker image with all build requirements and the SAM CLI installed: amazon/aws-sam-cli-build-image-provided. You can use this image as pipeline build and deploy steps.

Security and access management

Deploying a SAM template means creating any kind of resources into an AWS account. In order to make this process safe CloudFormation will use the permissions of the user who is executing the deployment to execute the calls for creating, modifying or deleting the resources. This means the user that perform the deploy need to be allowed to:

  • perform CloudFormation actions (DescribeStacks, CreateStack..)
  • upload artifacts and template (PutObject) to aws-sam-cli-managed-default- S3 bucket
  • create, update and delete the resource type describe in the template

Since any type of resource can be described within the SAM template (also IAM users, roles and policies) you have to be careful what you are deploying, you could give other AWS accounts access to your resources.

PRO tips

Deploy without any confirmation:

sam deploy --no-confirm-changeset ...

Deploy without specifying the deployment S3 bucket:

sam deploy --resolve-s3 ...

Deploy without the samconfig.toml:

sam deploy --profile example --stack-name sam-app --resolve-s3 --no-confirm-changeset --no-fail-on-empty-changeset --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND

Build and deploy:

sam build && sam deploy ...

Continuously deploy Lambda function changes (only for dev/test stacks):

sam sync --stack-name sam-app --watch

Originally written on Mar 10, 2023.

--

--

Fabio Gollinucci
Fabio Gollinucci

Written by Fabio Gollinucci

Backend Developer & Cloud Architect @ Bitbull

No responses yet