SAM (Serverless Application Model) — Cheat Sheet (DVA-C02)
Verified against AWS documentation on 2026-10-12 · ⚠️ = changed vs older material: learn the value shown here (older practice material may say otherwise; full list in notes/sam-guide.md#changed-vs-older-material) · ⚠️ unverified = not confirmed in AWS docs, don't rely on it · explanations and examples: notes/sam-guide.md.
SAM templates and the Serverless transform
| Topic | Current facts | Memory hook |
|---|---|---|
| Transform line | Transform: AWS::Serverless-2016-10-31 at the top level; a literal string, never a parameter or function |
One line makes it SAM |
| Required sections | Only Transform and Resources |
T + R |
| SAM-only section | Globals (no CloudFormation equivalent) |
|
| Template format | ⚠️ YAML or JSON | |
| How it expands | CloudFormation runs the hosted AWS::Serverless macro when it creates a change set; the stack shows AWS::Lambda::Function, AWS::IAM::Role, … |
Shorthand in, CloudFormation out |
| Processed template | aws cloudformation get-template --template-stage Processed (Original = submitted template) |
|
Direct create-stack |
Needs CAPABILITY_AUTO_EXPAND (macro without a change set) + CAPABILITY_IAM for generated roles |
|
| Several transforms | AWS::LanguageExtensions must be listed before AWS::Serverless-2016-10-31 |
Language first |
| Resource types | ⚠️ 13: Api, Application, CapacityProvider, Connector, Function, GraphQLApi, HttpApi, LayerVersion, MicrovmImage, NetworkConnector, SimpleTable, StateMachine, WebSocketApi (2026-10-12) |
|
| Automatic tag | lambda:createdBy = SAM on functions and generated roles |
|
| Mixed templates | Any CloudFormation resource, parameter, condition or output can sit next to SAM resources |
Function resource and event sources
| Topic | Current facts | Memory hook |
|---|---|---|
| What one function generates | AWS::Lambda::Function + role <FunctionLogicalId>Role (AWSLambdaBasicExecutionRole + Policies) unless Role is set |
Function + role + wiring |
| Code sources | CodeUri (local folder or s3://), InlineCode, or ImageUri / Metadata build with PackageType: Image |
|
| Defaults | PackageType: Zip, Timeout 3 s, Architectures x86_64 |
|
| Event types | 19, including Api, HttpApi, S3, SNS, SQS, Kinesis, DynamoDB, MSK, MQ, Schedule, ScheduleV2, EventBridgeRule, CloudWatchLogs, Cognito, IoTRule |
|
| Poll-based events | DynamoDB, Kinesis, MQ, MSK, SQS → AWS::Lambda::EventSourceMapping |
Pollers get a mapping |
| Schedules | Schedule → AWS::Events::Rule; ScheduleV2 → AWS::Scheduler::Schedule; ⚠️ AWS recommends ScheduleV2 |
V2 = Scheduler |
| Implicit REST API | Api event without RestApiId → ServerlessRestApi, stage Prod |
|
| Implicit HTTP API | HttpApi event without ApiId → ServerlessHttpApi, stage $default |
|
| S3 event bucket | Must be an AWS::S3::Bucket declared in the same template |
Same-template bucket |
Role set |
Policies, AssumeRolePolicyDocument, PermissionsBoundary, RolePath are ignored |
Your role, your policies |
Tracing: Active |
Adds AWSXrayWriteOnlyAccess only to roles SAM generates |
|
DeadLetterQueue |
SNS or SQS target for failed async invocations; SQS trigger → DLQ on the source queue |
|
| Function URL | AuthType AWS_IAM or NONE; InvokeMode BUFFERED (default) or RESPONSE_STREAM; targets $LATEST unless AutoPublishAlias |
URL follows the alias |
Function URL NONE |
SAM generates both lambda:InvokeFunctionUrl and lambda:InvokeFunction permissions (needed since Oct 2025) |
|
| SQS event | Queue ARN; BatchSize default 10 (1–10,000); FunctionResponseTypes: [ReportBatchItemFailures] |
APIs, tables, layers and other resources
| Topic | Current facts | Memory hook |
|---|---|---|
Api |
REST API; StageName required; Auth = Cognito, Lambda TOKEN/REQUEST, AWS_IAM, ApiKeyRequired, UsagePlan |
Api = REST |
Extra Stage stage |
SAM creates it by default; set OpenApiVersion (e.g. '3.0.1' in Globals → Api) to stop it |
OpenApiVersion kills Stage |
HttpApi |
HTTP API; default stage $default; JWT authorizers; CorsConfiguration needs DefinitionBody |
|
WebSocketApi |
RouteSelectionExpression + Routes ($connect, $disconnect, $default) required; stage default |
|
SimpleTable |
Single-attribute key (default id, String); no ProvisionedThroughput → PAY_PER_REQUEST; key can't change |
Simple = one key |
| Composite key, GSI, streams, TTL | Use AWS::DynamoDB::Table in the same template |
|
LayerVersion |
RetentionPolicy: Retain or Delete; new logical ID on each update keeps old versions; built only with Metadata → BuildMethod |
|
StateMachine |
Definition or DefinitionUri; Policies accept templates; Type STANDARD (default) or EXPRESS |
|
| External OpenAPI file | Intrinsic functions inside a DefinitionUri file aren't resolved → DefinitionBody + AWS::Include |
|
| Newer types | CapacityProvider (Lambda Managed Instances), MicrovmImage, NetworkConnector: not DVA-C02 material |
Globals
| Topic | Current facts | Memory hook |
|---|---|---|
| Supported types | ⚠️ 8: Function, Api, HttpApi, SimpleTable, StateMachine, CapacityProvider, MicrovmImage, NetworkConnector |
|
| Not allowed for functions | Role, Policies, Events, FunctionName, InlineCode, ImageUri, PackageType |
No global permissions or triggers |
| Primitives | Replaced by the resource value | Replace |
| Maps | Merged; on a duplicate key the resource wins | Merge |
| Lists | Additive; global entries come first | Prepend |
| Removing a global | Impossible; move the property out of Globals |
|
| Implicit APIs | Configured through Globals → Api (or declare an explicit AWS::Serverless::Api) |
|
| Scope | SAM resource types only, never plain AWS::Lambda::Function |
Policy templates and connectors
| Topic | Current facts | Memory hook |
|---|---|---|
Policies values |
Policy templates, AWS managed policy name, managed policy ARN, inline policy document | |
| Template without placeholders | - CloudWatchPutMetricPolicy: {}; without {} → Must specify valid parameter values for policy template |
Empty map, always |
| Template count | 78 listed (2026-10-12) | |
DynamoDBReadPolicy |
TableName → GetItem, Scan, Query, BatchGetItem, DescribeTable on the table and its indexes |
|
DynamoDBCrudPolicy |
Read actions + PutItem, UpdateItem, DeleteItem, BatchWriteItem, ConditionCheckItem |
CRUD, not admin |
S3ReadPolicy / S3CrudPolicy |
BucketName; object read / object read, write, delete on one bucket |
|
SQSPollerPolicy |
QueueName → ReceiveMessage, DeleteMessage(Batch), ChangeMessageVisibility(Batch), GetQueueAttributes |
Poller = consume |
SQSSendMessagePolicy / SNSPublishMessagePolicy |
QueueName → sqs:SendMessage* / TopicName → sns:Publish |
|
LambdaInvokePolicy |
FunctionName → lambda:InvokeFunction |
|
KMSDecryptPolicy |
KeyId must be a key ID, not an alias |
ID, not alias |
SSMParameterReadPolicy |
Name without leading slash; /a/b names → SSMParameterWithSlashPrefixReadPolicy |
Slash has its own template |
AWSSecretsManagerGetSecretValuePolicy |
SecretArn → secretsmanager:GetSecretValue |
|
| Connectors | Connectors on the source resource or AWS::Serverless::Connector; Destination Id (or Arn + Type); Permissions Read / Write |
Say what, not how |
| SAR and templates | Applications using only policy templates need no special capability acknowledgment |
sam init and sam build
| Topic | Current facts | Memory hook |
|---|---|---|
sam init non-interactive |
--no-interactive --name … --runtime … --app-template hello-world --dependency-manager … |
|
sam init output |
template.yaml, code folder, events/, tests/, README, samconfig.toml |
|
| Build output | .aws-sam/build + .aws-sam/build/template.yaml, used by local, package, deploy |
|
--use-container |
Builds in a Lambda-like container for native dependencies; needs Docker or Finch | Native deps → container |
--cached / --parallel |
Reuse unchanged artifacts (.aws-sam/cache) / build functions concurrently |
|
--build-in-source |
Node.js with Makefile or esbuild; incompatible with --use-container |
|
BuildMethod: makefile |
Target build-<LogicalId>, copy to $(ARTIFACTS_DIR); custom runtimes provided.al2023 |
|
BuildMethod: esbuild |
Node.js/TypeScript; defaults Minify: true, Target: es2020, Sourcemap: false |
|
| Image functions | Metadata: Dockerfile, DockerContext, DockerTag |
|
| Container runtime needed | Only for local testing and container builds: Docker or Finch | |
sam validate |
Checks the template; --lint adds cfn-lint |
sam package and sam deploy
| Topic | Current facts | Memory hook |
|---|---|---|
| Packaging | ⚠️ sam deploy packages implicitly; sam package optional (artifact template) |
Deploy packs itself |
| Artifact bucket | --s3-bucket or --resolve-s3 (stack aws-sam-cli-managed-default), never both |
|
| Template size | Above 51,200 bytes, --s3-bucket or --resolve-s3 is required |
|
| Container images | --image-repository, --image-repositories, or --resolve-image-repos (auto-create ECR) |
|
| Capabilities | CAPABILITY_IAM; custom names → CAPABILITY_NAMED_IAM; nested apps → CAPABILITY_AUTO_EXPAND; missing → InsufficientCapabilities |
|
--guided |
Prompts once, saves answers (e.g. capabilities = "CAPABILITY_IAM") to samconfig.toml |
|
| Review first | --no-execute-changeset (create only) or --confirm-changeset (prompt; off by default unless confirm_changeset = true in samconfig.toml) |
|
| Empty change set | sam deploy exits non-zero by default → CI uses --no-fail-on-empty-changeset |
|
| Failure handling | --on-failure ROLLBACK (default), DELETE, DO_NOTHING, or --disable-rollback; never both |
|
| Plain CLI equivalent | aws cloudformation package + aws cloudformation deploy (change set, no CAPABILITY_AUTO_EXPAND) |
|
| Clean-up | sam delete removes the stack and its S3/ECR artifacts; --no-prompts |
|
| Inspect | sam list endpoints, sam list resources, sam list stack-outputs |
samconfig and environments
| Topic | Current facts | Memory hook |
|---|---|---|
| Default file | samconfig.toml next to the template; YAML samconfig.yaml/.yml also supported |
|
| Lookup order | --config-file → samconfig.toml → samconfig.yaml / samconfig.yml |
|
--config-file path |
Relative to the template's folder | |
| Structure | version = 0.1; [env.command.parameters]; global = all commands; underscores (local_start_api, stack_name) |
|
| Environments | Default default; pick with --config-env prod |
One template, many envs |
| Precedence | CLI > config file > template defaults; command section > global |
CLI wins |
sam pipeline init |
Starters for CodePipeline, Jenkins, GitLab CI/CD, GitHub Actions, Bitbucket Pipelines; two stages | |
sam pipeline bootstrap |
Per --stage: pipeline IAM user (default) or OIDC, CloudFormation execution role, S3 bucket, optional ECR |
Prefer OIDC to keys |
SAM Accelerate and cloud testing
| Topic | Current facts | Memory hook |
|---|---|---|
sam sync scope |
Development stacks only (prompts to confirm); code syncs cause drift; --stack-name required |
Sync = dev |
Without --watch |
Build + one CloudFormation deployment, skipped for an unchanged template by --skip-deploy-sync (default) |
|
--watch |
Initial deploy, then code changes via service APIs, template changes via CloudFormation | |
--code |
Code-only sync of 10 resource types through Lambda, API Gateway and Step Functions APIs | Code skips CloudFormation |
--resource / --resource-id |
Narrow a --code sync by type / logical ID (nested: Stack/Resource) |
|
--skip-deploy-sync (default) |
Skips an unchanged infra deployment; forced after 7 days | |
--dependency-layer (default) |
Dependencies in an auto-created layer; turned off by --use-container |
|
| Default capabilities | CAPABILITY_NAMED_IAM + CAPABILITY_AUTO_EXPAND |
|
sam remote invoke |
Deployed Lambda, SQS, Kinesis Data Streams, Step Functions; --event, --event-file, --test-event-name |
Remote = real AWS |
sam remote test-event |
Shareable test events stored in the EventBridge schema registry | |
sam logs |
--tail, --filter, --include-traces; default start 10 minutes ago |
Local testing
| Topic | Current facts | Memory hook |
|---|---|---|
| Runtime | Local containers that mimic Lambda; Docker or Finch required | |
| Template used | .aws-sam/build first, so rebuild after code edits |
Built copy wins |
sam local invoke |
LogicalId; -e file.json or -e - (stdin); --no-event; --env-vars; --profile; -d debug port |
|
--env-vars JSON |
Parameters for all functions + per-function objects; function-specific wins; .env = global only |
|
| Output streams | Logs → stderr, result → stdout | |
sam local generate-event |
Prints a sample payload, e.g. s3 put --bucket … --key …; --help lists services |
Generate, then pipe |
sam local start-api |
127.0.0.1:3000; new container per request unless --warm-containers EAGER or LAZY |
API on 3000 |
| Reload on change | ⚠️ Automatic only without an .aws-sam build; otherwise rebuild; template change → restart |
|
sam local start-lambda |
127.0.0.1:3001; aws lambda invoke --endpoint-url http://127.0.0.1:3001 --no-verify-ssl |
Lambda on 3001 |
| Not emulated | ⚠️ DynamoDB (use DynamoDB local or a dev table), other AWS services, IAM checks | |
| Credentials | Local code uses your profile (--profile), not the execution role |
AutoPublishAlias
| Topic | Current facts | Memory hook |
|---|---|---|
| Generated | <fn>Version<hash> (MyFn.Version) and <fn>Alias<alias> (MyFn.Alias) |
|
| New version when | Code, Environment, MemorySize or SnapStart changes |
|
AutoPublishAliasAllProperties: true |
Any property change publishes (default false) |
|
| Parameter-only change | No new version (template text unchanged) → list AWS::LanguageExtensions first |
Same text, same version |
AutoPublishCodeSha256 |
Forces a version for new code at the same S3 key; overrides AllProperties |
|
ProvisionedConcurrencyConfig |
Only with AutoPublishAlias (set on the alias) |
|
| What uses the alias | SAM-generated event sources and the function URL | |
Without DeploymentPreference |
The alias moves to the new version instantly | |
VersionDeletionPolicy |
Delete, Retain or Snapshot for generated versions |
DeploymentPreference
| Topic | Current facts | Memory hook |
|---|---|---|
| Prerequisite | AutoPublishAlias (error otherwise) |
No alias, no shifting |
| Generated | ServerlessDeploymentApplication (1 per stack), <fn>DeploymentGroup (1 per function), CodeDeployServiceRole with AWSCodeDeployRoleForLambda unless Role |
|
| Canary types | Canary10Percent5Minutes, …10Minutes, …15Minutes, …30Minutes: 10 %, then the rest |
Canary = 2 steps |
| Linear types | Linear10PercentEvery1Minute, …2Minutes, …3Minutes, …10Minutes: +10 % per interval |
Linear = 10 steps |
AllAtOnce |
All traffic immediately; hooks still run | |
| CodeDeploy names | Mapped to CodeDeployDefault.Lambda<Type>; custom configuration names accepted |
|
Alarms |
Any alarm in ALARM → stop and roll back (DEPLOYMENT_STOP_ON_ALARM) |
Alarm = undo |
| Hooks | PreTraffic = BeforeAllowTraffic, PostTraffic = AfterAllowTraffic; via UpdatePolicy CodeDeployLambdaAliasUpdate |
|
| Hook contract | Call PutLifecycleEventHookExecutionStatus with DeploymentId, LifecycleEventHookExecutionId, Succeeded/Failed |
Report or fail |
| Hook deadline | No report within 1 hour → deployment fails | |
| Hook name | CodeDeployHook_ prefix with the generated service role |
|
| First deployment | Needs an existing version: deploy with the alias first | |
| Metric dimensions | FunctionName (all versions), Resource (version or alias), ExecutedVersion (compare two versions) |
Serverless Application Repository and nested applications
| Topic | Current facts | Memory hook |
|---|---|---|
| Publish | Metadata → AWS::ServerlessRepo::Application, then sam package, then sam publish |
Package, then publish |
| Bucket policy | serverlessrepo.amazonaws.com may s3:GetObject on bucket/* (scope with aws:SourceAccount) |
|
| New version | Same Name, new SemanticVersion |
|
| Visibility | Private (default, same Region), privately shared (accounts or Organization, same Region), public (all Regions) | |
| Public requirements | SemanticVersion and LicenseUrl |
|
| Share with accounts | put-application-policy --statements Principals=<account-id>,Actions=Deploy |
|
| Share with an Organization | Principals=*,PrincipalOrgIDs=<org-id>,Actions=Deploy,UnshareApplication |
Org needs Unshare |
Deploy action |
Covers get, change set, template, list versions, list dependencies, search | |
| Consumer capabilities | CAPABILITY_IAM, CAPABILITY_NAMED_IAM, CAPABILITY_RESOURCE_POLICY, CAPABILITY_AUTO_EXPAND |
|
| Blocked publications | AWSLambda_FullAccess on functions; iam:AttachRolePolicy, iam:PutRolePolicy or iam:* on all resources |
|
| Nested application | AWS::Serverless::Application with Location {ApplicationId, SemanticVersion} or a template URL/path → nested stack |
|
| Nested outputs | !GetAtt MyApp.Outputs.<OutputName> |
Numbers to know
| Item | Value | Note |
|---|---|---|
| Transform version | AWS::Serverless-2016-10-31 |
Literal string at the top level |
| Required template sections | 2 | Transform, Resources |
| SAM resource types | 13 ⚠️ | As of 2026-10-12 |
| Globals resource types | 8 ⚠️ | Template-anatomy page lists 6 |
| Function event types | 19 | Schedule and ScheduleV2 both exist |
| Function default timeout | 3 s | SAM Timeout default |
SQS event BatchSize |
Default 10, range 1–10,000 | Event source mapping |
| Policy templates listed | 78 | 2026-10-12; the list grows |
| Template size without S3 | 51,200 bytes | Larger → --s3-bucket or --resolve-s3 |
samconfig version |
0.1 | First line of the file |
| Config lookup steps | 3 | --config-file → .toml → .yaml/.yml |
sam local start-api port |
3000 | Host 127.0.0.1 |
sam local start-lambda port |
3001 | Host 127.0.0.1 |
| Docker-runtime alternatives | SAM CLI 1.47.0+ | Docker Desktop officially supported |
| Finch as container runtime | SAM CLI 1.145.0+ | macOS and Linux; Docker preferred when both run |
| Local Lambda authorizers | SAM CLI 1.80.0+ | start-api invokes them |
sam logs default start |
10 minutes ago | --start-time changes it |
sam sync --code resource types |
10 | Functions, layers, REST/HTTP APIs, state machines |
Forced infra deploy with --skip-deploy-sync |
After 7 days | Or many function changes |
sam sync default capabilities |
2 | CAPABILITY_NAMED_IAM, CAPABILITY_AUTO_EXPAND |
sam deploy --guided capability saved |
CAPABILITY_IAM |
When role creation is allowed |
esbuild Target default |
es2020 |
Minify default true, Sourcemap false |
| Version-publishing triggers (default) | 4 | Code, Environment, MemorySize, SnapStart |
| Predefined deployment types | 9 | 4 canary, 4 linear, 1 all at once |
| Canary first step | 10 % | Rest after 5, 10, 15 or 30 min |
| Linear step | 10 % every 1, 2, 3 or 10 min | Ten increments |
| Hook status deadline | 1 hour | Silence = failed deployment |
| Auto-rollback events | 3 | Failure, stop on alarm, stop on request |
| CodeDeploy applications per stack | 1 | ServerlessDeploymentApplication |
| Deployment groups | 1 per function | <fn>DeploymentGroup |
| SAR visibility levels | 3 | Private (default), privately shared, public |
| SAR consumer capabilities | 4 | IAM, NAMED_IAM, RESOURCE_POLICY, AUTO_EXPAND |
| Nested applications per application | 200 max | |
| Parameters per nested application | 60 max | |
| SAR application name | 1–140 characters | Description 1–256; up to 10 labels |
Decision rules
- If you see "make this CloudFormation template a SAM template", think
Transform: AWS::Serverless-2016-10-31. - If you see
create-stackfailing on a SAM template withInsufficientCapabilities, thinkCAPABILITY_AUTO_EXPAND(+CAPABILITY_IAM) or a change-set deployment. - If you see "the same runtime, timeout or variables for all functions", think
Globals→Function. - If you see a function overriding a global map or list, think merge (resource key wins) and prepend (global first).
- If you see an unwanted
Stagestage on a REST API, thinkOpenApiVersioninGlobals→Api. - If you see "table with sort key or GSI", think
AWS::DynamoDB::Table, notSimpleTable. - If you see "least privilege to one table, bucket or queue with the least effort", think a SAM policy template or a connector.
- If you see
Must specify valid parameter values for policy template, think the missing{}. - If you see
RoleplusPoliciesand missing permissions, thinkPoliciesis ignored whenRoleis set. - If you see an S3 event on another stack's bucket, think the bucket must be declared in this template.
- If you see native dependencies breaking after deployment, think
sam build --use-container. - If you see a CI deployment failing when nothing changed, think
--no-fail-on-empty-changeset. - If you see "review the change set before it runs", think
--no-execute-changesetor--confirm-changeset. - If you see dev and prod from one template, think
samconfig.tomlenvironments +--config-env. - If you see "fastest feedback in a development account", think
sam sync --watch. - If you see drift or an IAM change that never applied after code syncs, think
sam deploy(CloudFormation). - If you see "realistic event for a local test", think
sam local generate-event … | sam local invoke -e -. - If you see SDK integration tests against local functions, think
sam local start-lambda+--endpoint-urlport 3001. - If you see "test the API routes on my laptop", think
sam local start-api(port 3000). - If you see a local test passing but cloud calls denied, think local runs use your credentials and never check IAM.
- If you see "pipeline without long-term keys", think
sam pipeline bootstrap --permissions-provider oidc. - If you see "new version + alias on every deployment", think
AutoPublishAlias. - If you see a parameter-only change not reaching the alias, think
AWS::LanguageExtensionsbefore the serverless transform. - If you see "10 % for N minutes, then everyone", think
Canary10Percent<N>Minutes. - If you see "10 % more every N minutes", think
Linear10PercentEvery<N>Minute(s). - If you see automatic rollback on errors during a release, think
DeploymentPreferenceAlarms. - If you see tests before or after the traffic shift, think
PreTraffic/PostTraffichooks reporting withPutLifecycleEventHookExecutionStatus. - If you see CodeDeploy unable to invoke a hook, think the
CodeDeployHook_name prefix (or a customRole). - If you see "share a serverless app with the whole organization", think
put-application-policywithPrincipalOrgIDs+UnshareApplication. - If you see "reuse a component across templates", think
AWS::Serverless::Application+CAPABILITY_AUTO_EXPAND.
Memory hooks
- One line makes it SAM: the
Transform. - T + R: the only required sections.
- Shorthand in, CloudFormation out.
- Replace, merge, prepend: the Globals override rules.
- No global permissions or triggers:
PoliciesandEventsstay on the function. - Your role, your policies:
Roleswitches offPolicies. - Same-template bucket for S3 events.
- Empty map, always:
{}for templates without placeholders. - ID, not alias:
KMSDecryptPolicy. - Native deps → container build.
- Deploy packs itself:
sam packageis optional. - Empty change set = red build until
--no-fail-on-empty-changeset. - One template, many environments:
--config-env. - CLI wins over the file; the command section wins over
global. - Sync is for dev; deploy is for prod.
- Code skips CloudFormation; templates don't.
- API on 3000, Lambda on 3001.
- Built copy wins: rebuild after edits.
- Generate, then pipe:
generate-event | invoke -e -. - Same text, same version: parameters alone don't publish.
- No alias, no shifting.
- Canary = two steps, linear = ten steps.
- Report or fail within the hour.
- Org sharing needs Unshare.