SAM (Serverless Application Model) — DVA-C02 Mastery Guide
- Sources: course chapter 18 (AWS Serverless Application Model). The course serves as the syllabus only; all wording here is original.
- Written 2026-10-12; values checked against AWS docs on 2026-10-12 (AWS SAM Developer Guide, CloudFormation, CodeDeploy, Serverless Application Repository and Lambda documentation). The marker
⚠️ Changed: <current>. Older material may say <old>.flags a value or behaviour that differs from the course or older practice tests: learn the current value.⚠️ unverifiedmarks something AWS documentation did not confirm: don't build an exam answer on it. Counts that keep growing (resource types, policy templates, CLI options) carry their date. Every change is listed in Changed vs older material.- Tier 2 (deployment and messaging), bank target 30 questions. Domain: Deployment (the only domain of this module).
- How to use it:
/explain <topic>teaches from these sections (concept → exam facts → developer angle → traps → 3 check questions);/quiz samasks bank questions whosesource_notelinks point at the## N.headings below;/drill samfires short recall prompts fromnotes/sam-cheat-sheet.md. Suggested loop: read a section and answer its practice questions before opening the answers →/explainwhat is still unclear →/quiz sam→/drill sam.- Owned by other modules (one-line pointers only here): Lambda versions, alias weights, concurrency, SnapStart and limits →
notes/lambda-guide.md; API Gateway stages, authorizers, CORS and canary releases →notes/api-gateway-guide.md; template sections, intrinsic functions, change sets, rollback and nested stacks →notes/cloudformation-guide.md; CodeDeploy appspec, EC2/ECS deployments and CodePipeline →notes/cicd-guide.md; CDK and using the SAM CLI with CDK →notes/cdk-guide.md; Step Functions and AppSync →notes/other-services-guide.md; X-Ray and CloudWatch →notes/monitoring-guide.md; CLI profiles and credentials →notes/cli-sdk-policies-guide.md.
How SAM appears on DVA-C02
SAM is a Deployment-domain topic. Questions treat it as the shortest path from code to a working serverless stack and ask which SAM feature or command solves a delivery problem:
- Prepare application artifacts: the template shorthand (
Transform,AWS::Serverless::*,Globals),sam build(dependencies, build containers, esbuild),sam packageand the S3/ECR artifacts it produces. - Test in development environments:
sam local invokewith generated events,sam local start-api/start-lambda,sam sync --watchagainst a dev stack,sam remote invoke. - Automate deployment testing and deploy safely:
AutoPublishAlias+DeploymentPreference(canary, linear, all at once), pre- and post-traffic hooks, CloudWatch alarms and automatic rollback; per-environment settings insamconfig.toml;sam pipelinestarters. - Least privilege without IAM expertise: policy templates and connectors.
- Reuse and sharing: the AWS Serverless Application Repository (SAR) and nested applications.
Typical question shapes: "Which line turns a CloudFormation template into a SAM template?"; "Which command gives the fastest feedback during development?"; "Release the new version to 10 % of traffic, then to everyone, with automatic rollback"; "Grant the function read access to one table with the least effort"; "Test the function locally with an S3 event"; "Deploy the same template to dev and prod with different parameters"; "Share the application with every account in the organization".
Deciding constraints: LEAST operational overhead (SAM shorthand, policy templates and the built-in CodeDeploy integration instead of scripts), fastest feedback (sam sync, local tests), safest release (canary or linear + alarms + hooks), least privilege (resource-scoped templates, connectors, OIDC for pipelines), fewest code changes (one template property instead of new tooling).
Out of scope: Docker or operating-system administration for the local tools, and network design for functions in a VPC (see notes/vpc-guide.md).
| # | Topic | Why it is on the exam |
|---|---|---|
| 1 | SAM templates and the Serverless transform | The Transform line, required sections, how the shorthand becomes CloudFormation |
| 2 | The Function resource and event sources | What one AWS::Serverless::Function generates; events, roles, URLs, DLQs |
| 3 | APIs tables layers and other serverless resources | REST vs HTTP vs WebSocket APIs, SimpleTable limits, layers, state machines |
| 4 | The Globals section | Shared settings and the replace / merge / prepend override rules |
| 5 | Permissions with policy templates and connectors | Least privilege in one line; the {} rule; connectors |
| 6 | Creating and building projects with sam init and sam build | Scaffolding, dependency builds, build containers, esbuild, validation |
| 7 | Packaging and deploying with sam package and sam deploy | Artifacts in S3/ECR, change sets, capabilities, CI flags, clean-up |
| 8 | Configuration files and multiple environments | samconfig.toml environments, precedence, sam pipeline |
| 9 | SAM Accelerate and testing in the cloud | sam sync modes and drift, sam remote invoke, logs and traces |
| 10 | Local testing with sam local and generated events | invoke, generate-event, start-api, start-lambda, limits of local tests |
| 11 | Automatic versions and aliases with AutoPublishAlias | When a new version is published and what points at the alias |
| 12 | Traffic shifting with DeploymentPreference hooks and alarms | Canary, linear, all at once; hooks, alarms, rollback, generated CodeDeploy resources |
| 13 | Serverless Application Repository and nested applications | Publish, share, capabilities, AWS::Serverless::Application |
1. SAM templates and the Serverless transform
Concept
- AWS SAM has two halves: a template specification (CloudFormation plus short-hand serverless resource types) and the SAM CLI (
sam init,build,local,deploy,sync, …). Each works without the other: CloudFormation can deploy a SAM template directly, and the SAM CLI can test functions declared in plain CloudFormation. - A template becomes a SAM template through one top-level line:
Transform: AWS::Serverless-2016-10-31. During deployment CloudFormation runs this transform (a macro hosted by CloudFormation) and expands everyAWS::Serverless::*resource into ordinary resources: a function becomes anAWS::Lambda::Function, its execution role, permissions and event source mappings. - Everything else is plain CloudFormation:
Parameters,Mappings,Conditions,Outputs, intrinsic functions and anyAWS::*resource can sit next to SAM resources in the same file. - Why developers use it: a few lines replace hundreds of CloudFormation lines (AWS's own example turns 23 SAM lines into more than 200), while deployments keep CloudFormation's change sets and rollback.
Exam facts
- Only
TransformandResourcesare required. Optional sections:Globals(SAM only, §4),Description,Metadata,Parameters,Mappings,Conditions,Outputs, plusAWSTemplateFormatVersion. Sections may appear in any order. - The transform value must be the literal string
AWS::Serverless-2016-10-31declared at the top level; a parameter or intrinsic function can't supply it. - With several transforms, list them;
AWS::LanguageExtensionsmust come beforeAWS::Serverless-2016-10-31. - ⚠️ Changed: SAM templates can be written in YAML or JSON (the transform reference shows both syntaxes). Older material may say all SAM configuration is YAML.
- CloudFormation runs the transform when it creates a change set, and
sam deployalways works through change sets. Creating a stack directly from a template that contains macros (theAWS::Serverlesstransform included) without a change set requiresCAPABILITY_AUTO_EXPAND; roles that SAM generates still needCAPABILITY_IAM(orCAPABILITY_NAMED_IAMwhen roles have custom names). - ⚠️ Changed: SAM has 13 resource types (2026-10-12):
Api,Application,CapacityProvider,Connector,Function,GraphQLApi,HttpApi,LayerVersion,MicrovmImage,NetworkConnector,SimpleTable,StateMachine,WebSocketApi. Older material may say SAM offers onlyFunction,ApiandSimpleTable(or the original seven types). - The deployed stack lists the expanded resources (
AWS::Lambda::Function,AWS::IAM::Role, …).aws cloudformation get-template --template-stage Processedreturns the expanded template;Originalreturns the template you submitted. - SAM tags each function and every role it generates with
lambda:createdBy=SAM.
Developer angle
A complete minimal SAM template (HTTP API → function → table):
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Parameters:
Stage:
Type: String
AllowedValues: [dev, prod]
Default: dev
Resources:
OrdersTable:
Type: AWS::Serverless::SimpleTable
CreateOrderFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/create_order/
Handler: app.handler
Runtime: python3.13
Environment:
Variables:
TABLE_NAME: !Ref OrdersTable
STAGE: !Ref Stage
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref OrdersTable
Events:
CreateOrder:
Type: HttpApi
Properties:
Path: /orders
Method: post
Outputs:
ApiUrl:
Value: !Sub 'https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com/'
Check the template, then look at what the transform produced:
sam validate --lint # SAM validation plus cfn-lint rules
sam list resources --stack-name orders-dev # logical IDs generated by the transform
aws cloudformation get-template --stack-name orders-dev \
--template-stage Processed --query TemplateBody
Traps
- Trap: "Put the transform name in a parameter so each environment can choose it." → Reality: the value must be the literal string, at the top level.
- Trap: "A SAM template may only contain
AWS::Serverless::*resources." → Reality: any CloudFormation resource, parameter, condition or output can be mixed in. - Trap: "
sam deploybypasses CloudFormation." → Reality: it creates and executes a change set; onlysam synccode syncs bypass CloudFormation (§9). - Trap: "
create-stackwith onlyCAPABILITY_IAMworks for any SAM template." → Reality: a directcreate-stackfrom a template with the transform also needsCAPABILITY_AUTO_EXPAND.
Practice questions
-
A developer copies a template from a colleague. It declares several
AWS::Serverless::Functionresources, but CloudFormation rejects it because it does not recognize those resource types. Which change makes the template deployable with the LEAST effort?- A. Add
AWSTemplateFormatVersion: '2010-09-09'as the first line of the template file. - B. Add
Transform: AWS::Serverless-2016-10-31at the top level of the template. - C. Move the function definitions into a
Globalssection. - D. Deploy the template with the
CAPABILITY_NAMED_IAMcapability.
- A. Add
-
A CI job creates a stack by calling
aws cloudformation create-stackdirectly with a SAM template, without creating a change set first. The template's functions use execution roles that SAM generates without custom names. Which TWO changes to the call are required? (Select TWO.)- A. Pass
--disable-rollback. - B. Add
CAPABILITY_IAMto--capabilities. - C. Add
CAPABILITY_RESOURCE_POLICYto--capabilities. - D. Add
CAPABILITY_AUTO_EXPANDto--capabilities. - E. Pass a CloudFormation service role with
--role-arn.
- A. Pass
Answers
- B. Without the transform declaration CloudFormation treats
AWS::Serverless::*as unknown types. A is optional and changes nothing; C is wrong becauseGlobalsholds shared properties, not resources; D concerns IAM acknowledgment, not resource types. - B, D. Generated roles are IAM resources (
CAPABILITY_IAM), and creating a stack directly from a template with a macro needsCAPABILITY_AUTO_EXPAND. C is an acknowledgment used by the Serverless Application Repository, not a valueCreateStackaccepts; A changes failure handling and E changes which role CloudFormation uses, and neither acknowledges anything.
2. The Function resource and event sources
Concept
AWS::Serverless::Functiondeclares a Lambda function plus what it needs to run: SAM always creates theAWS::Lambda::Functionand, unless you passRole, an execution role named<FunctionLogicalId>RolewithAWSLambdaBasicExecutionRoleand whateverPoliciesadd (§5).- Code comes from
CodeUri(a local folder that the CLI uploads at deploy time, or ans3://URI), fromInlineCode, or, withPackageType: Image, fromImageUri(or a Dockerfile declared inMetadata, §6). Eventsis a map of named triggers. Each entry has aTypeand type-specificProperties, and SAM writes the wiring for you: invoke permissions for push sources (API Gateway, S3, SNS, …), event source mappings for poll-based sources, EventBridge rules for event patterns andSchedule, EventBridge Scheduler schedules forScheduleV2.
Exam facts
- Zip functions need
Handler,Runtimeand eitherCodeUriorInlineCode; Image functions needImageUriorMetadatabuild entries (which win if both are present). Defaults:PackageType: Zip,Timeout3 s,Architecturesx86_64. - Event types (19):
AlexaSkill,Api,CloudWatchEvent,CloudWatchLogs,Cognito,DocumentDB,DynamoDB,EventBridgeRule,HttpApi,IoTRule,Kinesis,MQ,MSK,S3,Schedule,ScheduleV2,SelfManagedKafka,SNS,SQS. - Generated wiring:
DynamoDB,Kinesis,MQ,MSK,SQS→AWS::Lambda::EventSourceMapping;EventBridgeRule,Schedule,CloudWatchEvent→AWS::Events::Rule;ScheduleV2→AWS::Scheduler::Schedule;IoTRule→AWS::IoT::TopicRule. - ⚠️ Changed: AWS recommends the
ScheduleV2event type (EventBridge Scheduler) for schedules. Older material may say to use theScheduleevent, which creates an EventBridge (CloudWatch Events) rule; it still works. SQSevent:Queue(ARN, required),BatchSize(default 10, 1–10,000),FunctionResponseTypes: [ReportBatchItemFailures],FilterCriteria,ScalingConfig.MaximumConcurrency,MaximumBatchingWindowInSeconds(queue behaviour:notes/sqs-sns-kinesis-guide.md).- An
Apievent withoutRestApiIdcreates the implicit REST APIServerlessRestApi(stageProd); anHttpApievent withoutApiIdcreates the implicit HTTP APIServerlessHttpApi(stage$default). Details in §3. - An
S3event accepts only a bucket declared in the same template (!Refto anAWS::S3::Bucket); a bucket owned by another stack can't be used there. Role(an ARN) replaces the generated role:Policies,AssumeRolePolicyDocument,PermissionsBoundaryandRolePaththen have no effect.Tracing: ActiveorPassThroughmakes SAM attachAWSXrayWriteOnlyAccess, but only to a role it generates (tracing itself:notes/monitoring-guide.md).DeadLetterQueue(Type: SNSorSQSplusTargetArn) receives failed asynchronous invocations; for an SQS trigger, configure the DLQ on the source queue instead.EventInvokeConfigdestinations can even create the SNS topic or SQS queue (<fn>OnSuccessTopic,<fn>OnFailureQueue, …) when no ARN is given (async behaviour:notes/lambda-guide.md).FunctionUrlConfig:AuthTypeAWS_IAMorNONE(required),InvokeModeBUFFERED(default) orRESPONSE_STREAM,Cors. The URL targets$LATESTunlessAutoPublishAliasis set, then the alias. WithAuthType: NONE, SAM generates twoAWS::Lambda::Permissionresources, covering bothlambda:InvokeFunctionUrlandlambda:InvokeFunction, which new function URLs need since October 2025 (seenotes/current-facts.md, lambda rows); with the CLI or plain CloudFormation you add both yourself.- References:
!Ref MyFunction→ function name;!GetAtt MyFunction.Arn→ ARN;MyFunctionRole→ generated role's logical ID;!GetAtt MyFunctionUrl.FunctionUrl→ function URL. - SAM can't parse intrinsic functions inside
CodeUri; the documented workaround is theAWS::LanguageExtensionstransform.
Developer angle
Three functions, three trigger styles (push, poll, schedule):
Globals:
Function:
Runtime: python3.13
Handler: app.handler
Resources:
UploadsBucket:
Type: AWS::S3::Bucket
OrdersQueue:
Type: AWS::SQS::Queue
ReportFailures:
Type: AWS::SQS::Queue
ThumbnailFunction: # push: S3 notification + invoke permission
Type: AWS::Serverless::Function
Properties:
CodeUri: src/thumbnail/
Events:
NewUpload:
Type: S3
Properties:
Bucket: !Ref UploadsBucket # must be a bucket of this template
Events: s3:ObjectCreated:*
OrderWorkerFunction: # poll: event source mapping
Type: AWS::Serverless::Function
Properties:
CodeUri: src/worker/
Events:
FromQueue:
Type: SQS
Properties:
Queue: !GetAtt OrdersQueue.Arn
BatchSize: 10
FunctionResponseTypes: [ReportBatchItemFailures]
NightlyReportFunction: # schedule: EventBridge Scheduler
Type: AWS::Serverless::Function
Properties:
CodeUri: src/report/
DeadLetterQueue: # failed asynchronous invocations
Type: SQS
TargetArn: !GetAtt ReportFailures.Arn
Events:
Nightly:
Type: ScheduleV2
Properties:
ScheduleExpression: cron(0 2 * * ? *)
After deployment, sam list resources --stack-name media-dev shows the generated roles, the S3 invoke permission, the event source mapping and the EventBridge Scheduler schedule; sam list endpoints lists function URLs and API endpoints when a stack has them.
Traps
- Trap: "Point the
S3event at the bucket another stack owns." → Reality: theBucketproperty accepts only a bucket created in the same template. - Trap: "Set both
RoleandPoliciesto add a template on top of my role." → Reality: withRole, SAM ignoresPolicies; attach the extra policy to that role. - Trap: "The function's
DeadLetterQueuecatches messages that keep failing from its SQS trigger." → Reality: it serves asynchronous invocations; give the source queue a redrive policy. - Trap: "A function URL always targets the latest published alias." → Reality:
$LATEST, unlessAutoPublishAliasis set. - Trap: "An
Apievent creates an HTTP API." → Reality:Api= REST API (ServerlessRestApi);HttpApi= HTTP API (ServerlessHttpApi).
Practice questions
-
A developer adds an
S3event to a function so that uploads trigger it. The bucket belongs to another team's stack, and the deployment fails. The teams agree that this application can create and own its own uploads bucket instead. What should the developer do?- A. Pass the other stack's exported bucket name to the event's
Bucketproperty withFn::ImportValue. - B. Add the
S3ReadPolicypolicy template for the existing bucket to the function. - C. Declare the bucket in this template and reference it with
!Refin the event'sBucketproperty. - D. Deploy the stack with the
CAPABILITY_AUTO_EXPANDcapability.
- A. Pass the other stack's exported bucket name to the event's
-
A developer deploys a function that declares
Role: arn:aws:iam::111122223333:role/orders-exec, aPoliciesentry withDynamoDBReadPolicy, andTracing: Active. After deployment, reads fail withAccessDeniedand no traces arrive in X-Ray. Which TWO statements explain the behaviour? (Select TWO.)- A. SAM ignores the
Policiesproperty whenRoleis specified. - B. SAM merges policy templates into the role passed in
Role. - C. SAM adds
AWSXrayWriteOnlyAccessonly to execution roles that it generates. - D. SAM rejects
Tracing: Activefor functions that use an existing role. - E. Policy templates take effect only when they are declared under
Globals.
- A. SAM ignores the
Answers
- C. The S3 event only accepts a reference to a bucket defined in the same template. A fails because the property accepts only such a reference; B grants access but creates no trigger; D is unrelated to event wiring.
- A, C. A supplied role replaces the generated one, so neither
Policiesnor the automatic X-Ray policy is applied; add both permissions toorders-exec. B is the opposite of the documented behaviour; D is wrong because tracing is configured but lacks permissions; E is wrong becausePoliciescan't be set inGlobalsat all.
3. APIs tables layers and other serverless resources
Concept
Beyond functions, SAM offers shorthand for the other serverless building blocks: three API Gateway API types, a single-key DynamoDB table, Lambda layers, Step Functions state machines, AppSync GraphQL APIs, nested applications (§13), connectors (§5) and, more recently, Lambda compute resources. Each expands into the matching CloudFormation resources; for anything the shorthand can't express, declare the full CloudFormation type in the same template.
Exam facts
| SAM type | Expands to | Facts to know |
|---|---|---|
Api |
AWS::ApiGateway::RestApi, Deployment, Stage |
REST API. StageName required (implicit API: Prod). Auth: Cognito user pool, Lambda TOKEN / REQUEST and AWS_IAM authorizers, ApiKeyRequired, UsagePlan (adds usage plan, key and API key resources), ResourcePolicy. Also Cors, CanarySetting, caching, EndpointConfiguration, OpenAPI through DefinitionBody or DefinitionUri |
HttpApi |
AWS::ApiGatewayV2::Api, Stage |
HTTP API (lower cost and latency); default stage $default; Auth with JWT authorizers among others; CorsConfiguration needs DefinitionBody |
WebSocketApi |
AWS::ApiGatewayV2::Api (WebSocket), Stage |
RouteSelectionExpression (for example $request.body.action) and Routes ($connect, $disconnect, $default, custom) are required; stage default unless StageName; Auth applies to $connect |
SimpleTable |
AWS::DynamoDB::Table |
Single-attribute primary key only (default id, String); without ProvisionedThroughput the table is PAY_PER_REQUEST; PrimaryKey can't change after creation; sort keys, indexes, streams or TTL → AWS::DynamoDB::Table |
LayerVersion |
AWS::Lambda::LayerVersion |
ContentUri, CompatibleRuntimes, CompatibleArchitectures, RetentionPolicy: Retain or Delete; SAM changes the logical ID on each update so old versions survive; since CloudFormation added UpdateReplacePolicy, AWS recommends plain AWS::Lambda::LayerVersion with UpdateReplacePolicy: Retain instead, which also keeps the old version when an update replaces it |
StateMachine |
AWS::StepFunctions::StateMachine |
Definition or DefinitionUri; DefinitionSubstitutions; Policies accepts policy templates; Type STANDARD (default) or EXPRESS; Events; optional AutoPublishAlias + DeploymentPreference |
GraphQLApi |
AppSync resources | GraphQL API with resolvers (notes/other-services-guide.md) |
Application |
AWS::CloudFormation::Stack |
Nested application from SAR or a template (§13) |
Connector |
IAM managed policies or resource permissions (AWS::Lambda::Permission, queue or topic policies) |
Read and Write permissions between resources (§5) |
CapacityProvider |
AWS::Lambda::CapacityProvider |
Lambda Managed Instances on EC2; VpcConfig required; functions attach through CapacityProviderConfig |
MicrovmImage, NetworkConnector |
AWS::Lambda::MicrovmImage, AWS::Lambda::NetworkConnector |
Newer Lambda MicroVM images and VPC egress connectors; not DVA-C02 material |
- SAM creates an extra REST API stage named
Stageby default; settingOpenApiVersion(for example'3.0.1', often underGlobals→Api) prevents it. - A local
DefinitionUri(orLocation,ContentUri,DefinitionUriof a state machine) is uploaded only throughsam package/sam deploy. Intrinsic functions inside an external OpenAPI file are not resolved: inline the definition withDefinitionBodyand theAWS::Includetransform. CorsonApimakes SAM edit the OpenAPI definition; onHttpApi,CorsConfiguration: trueallows all origins.MergeDefinitions: truemerges the paths SAM generates from events into your inlineDefinitionBody(not usable withDefinitionUri).- Return values:
!Ref MyApi→ API ID (stage resource:MyApi.Stage);!Ref MyTable→ table name;!Ref MyLayer→ layer version ARN;!Ref MyStateMachine→ state machine ARN. - A layer is built by
sam buildonly if it hasMetadata→BuildMethod(a runtime identifier such aspython3.12, ormakefile); otherwise SAM copiesContentUrias it is. Python layer code belongs inpython/, Node.js innodejs/node_modules/.
Developer angle
REST API with a Cognito authorizer and CORS, plus a layer that sam build builds:
Globals:
Api:
OpenApiVersion: '3.0.1' # no extra "Stage" stage
Resources:
ShopUserPool:
Type: AWS::Cognito::UserPool
OrdersApi:
Type: AWS::Serverless::Api
Properties:
StageName: prod
Cors: "'https://shop.example.com'"
Auth:
DefaultAuthorizer: ShopUsers
Authorizers:
ShopUsers:
UserPoolArn: !GetAtt ShopUserPool.Arn
SharedLibs:
Type: AWS::Serverless::LayerVersion
Properties:
ContentUri: layers/shared/
CompatibleRuntimes: [python3.12]
RetentionPolicy: Retain
Metadata:
BuildMethod: python3.12 # sam build installs the layer's requirements
ListOrdersFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/list_orders/
Handler: app.handler
Runtime: python3.12
Layers: [!Ref SharedLibs]
Events:
List:
Type: Api
Properties:
RestApiId: !Ref OrdersApi
Path: /orders
Method: get
Traps
- Trap: "
StageNameis optional onAWS::Serverless::Api." → Reality: it is required; only the implicit API getsProdautomatically. - Trap: "Add a sort key to
SimpleTable." → Reality: single-attribute keys only; useAWS::DynamoDB::Tablefor composite keys, indexes, streams or TTL. - Trap: "
!Subinside an OpenAPI file referenced byDefinitionUrigets resolved." → Reality: it doesn't; useDefinitionBodywithAWS::Include. - Trap: "Updating a
LayerVersiondeletes the previous layer version." → Reality: SAM gives each update a new logical ID, so old versions stay;RetentionPolicycontrols deletion with the stack. - Trap: "
HttpApiCORS works with an OpenAPI file in S3." → Reality:CorsConfigurationneedsDefinitionBody.
Practice questions
-
A team's REST API is built only from
Apievents on several functions, and after deployment it shows two stages,ProdandStage. The team wants onlyProdwith the fewest template changes. What should the developer do?- A. Delete the
Stagestage in the API Gateway console after each deployment. - B. Change every function's events from
ApitoHttpApi. - C. Declare an
AWS::Serverless::ApiwithStageName: Prodand reference it withRestApiIdfrom every event. - D. Set
OpenApiVersion: '3.0.1'underGlobals→Api.
- A. Delete the
-
A developer is defining a DynamoDB table in a SAM template. Items need a partition key and a sort key, and one access pattern needs a global secondary index. Which TWO statements are correct? (Select TWO.)
- A. Add the sort key as a second entry of the
SimpleTablePrimaryKeyproperty. - B. SAM templates can't contain
AWS::DynamoDB::Tableresources, so a separate stack is needed. - C. Declare the table as an
AWS::DynamoDB::Tableresource in the SAM template. - D.
SimpleTablecreates a provisioned table with 5 read and 5 write capacity units by default. - E.
AWS::Serverless::SimpleTablesupports only a single-attribute primary key.
- A. Add the sort key as a second entry of the
Answers
- D.
OpenApiVersionstops SAM from creating its defaultStagestage, andGlobalsreaches the implicit API in one place. A is manual and repeats on every deployment; B changes the API type and its features; C adds a resource and edits every event, and SAM still createsStageunlessOpenApiVersionis set. - C, E.
SimpleTablehas a single-attribute key, so a composite key and an index needAWS::DynamoDB::Table, which SAM templates accept like any CloudFormation resource. A is not supported; B is false; D is false because aSimpleTablewithoutProvisionedThroughputusesPAY_PER_REQUEST.
4. The Globals section
Concept
Globalsdeclares settings once and lets every resource of a supported type inherit them, such as one runtime, timeout, tracing mode and set of environment variables for all functions.- It exists only in SAM templates. Only listed resource types and listed properties are allowed: anything else is rejected, either because it could open security issues or because it would make templates hard to read.
- A resource can override an inherited value but can never remove it, so a setting that only some resources want does not belong in
Globals.
Exam facts
- ⚠️ Changed:
Globalssupports 8 resource types (Globals reference, 2026-10-12):Function,Api,HttpApi,SimpleTable,StateMachine,CapacityProvider,MicrovmImage,NetworkConnector; the template-anatomy page still lists the first six. Older material may say onlyFunction,Api,HttpApiandSimpleTable. Functionglobals includeRuntime,Handler,CodeUri,Timeout,MemorySize,Environment,Layers,Tracing,VpcConfig,Architectures,AutoPublishAlias,DeploymentPreference,ProvisionedConcurrencyConfig,ReservedConcurrentExecutions,SnapStart,LoggingConfig,PermissionsBoundary,FunctionUrlConfig,Tags,KmsKeyArn,EphemeralStorage,DeadLetterQueue,EventInvokeConfig,RuntimeManagementConfig.- Not allowed in
Globals→Function:Role,Policies,Events,FunctionName,InlineCode,ImageUri,PackageType(they are absent from the supported list). Apiglobals includeAuth,Cors,OpenApiVersion,MethodSettings,TracingEnabled,Variables,EndpointConfiguration,CacheClusterEnabled,AccessLogSetting,BinaryMediaTypes,Domain,GatewayResponses;HttpApiglobals:AccessLogSettings,Auth,PropagateTags,StageVariables,Tags;SimpleTable:SSESpecification;StateMachine:PropagateTags.- Override rules:
- Primitives (strings, numbers, Booleans) are replaced by the resource value.
- Maps are merged; on duplicate keys the resource entry wins.
- Lists are additive: global entries are placed before the resource's entries.
- Implicit APIs created from
Apievents have no resource of your own to configure, so their settings go inGlobals→Api(for exampleOpenApiVersion,Auth,Cors); otherwise declare an explicitAWS::Serverless::Api.
Developer angle
Globals:
Function:
Runtime: python3.13
Timeout: 15
Tracing: Active
Environment:
Variables:
STAGE: prod
TABLE_NAME: orders
Layers:
- !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:layer:shared-libs:3'
Api:
OpenApiVersion: '3.0.1'
Resources:
ReportFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/report/
Handler: app.handler
Timeout: 60 # primitive: replaces 15
Environment:
Variables:
TABLE_NAME: reports # map: overrides this key only
FORMAT: csv # map: added next to STAGE
Layers: # list: result is [shared-libs:3, pdf-libs:7]
- !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:layer:pdf-libs:7'
Effective configuration of ReportFunction: runtime python3.13, timeout 60 s, tracing Active, variables STAGE=prod, TABLE_NAME=reports, FORMAT=csv, layers shared-libs:3 then pdf-libs:7.
Traps
- Trap: "A function that defines its own
Environmentloses the global variables." → Reality: maps merge; only duplicate keys are overridden. - Trap: "A function's list replaces the global list." → Reality: lists are additive, with the global entries first.
- Trap: "Put shared
PoliciesorEventsinGlobals." → Reality: neither is supported; repeat them per resource (or use connectors / a shared managed policy). - Trap: "Set the property to null on one function to opt out of a global." → Reality: a resource can't remove a global property; move it out of
Globals. - Trap: "
Globalsalso configuresAWS::Lambda::Functionresources." → Reality: only SAM resource types inherit it.
Practice questions
-
A developer's template sets
Layers: [!Ref LoggingLayer]underGlobals→Function, and one function declaresLayers: [!Ref ImageLayer]. Which layers does that function get after deployment, and in which order?- A. Only
ImageLayer. - B.
LoggingLayer, thenImageLayer. - C.
ImageLayer, thenLoggingLayer. - D. None, because the template fails validation with a duplicate property.
- A. Only
-
A platform team moves shared settings of 30 functions into
Globalsto shorten the template. Which TWO settings must stay on each function resource? (Select TWO.)- A.
Timeout - B.
Policies - C.
Tracing - D.
Events - E.
Environment
- A.
Answers
- B. Lists are additive and the global entries come first. A describes replacement, which applies to primitives only; C reverses the documented order; D is wrong because overriding is allowed.
- B, D.
PoliciesandEventsare not in the supportedGlobalsproperty list. A, C and E are supported globals (Timeoutis replaced andEnvironmentmerged when a function overrides them).
5. Permissions with policy templates and connectors
Concept
- A function's generated role starts with
AWSLambdaBasicExecutionRole;Policies(on functions and state machines) appends more.Policiesaccepts four kinds of values: SAM policy templates (parameterized, scoped to one resource), the name of an AWS managed policy, the ARN of an AWS or customer managed policy, and an inline policy document. - Policy templates turn least privilege into one line:
DynamoDBReadPolicywithTableName: !Ref OrdersTableexpands into a statement that allows only read actions on that table and its indexes. - Connectors go one step further: you state that a source resource needs
Readand/orWriteaccess to a destination, and SAM composes the policy (and, for event sources, the resource permissions) for you.
Exam facts
- Syntax: every template is a map of its placeholder values; a template without placeholders still needs an empty map,
- CloudWatchPutMetricPolicy: {}. Forgetting it makessam buildfail withMust specify valid parameter values for policy template '<name>'. Managed policies by name or ARN need no{}. - 78 policy templates are listed (2026-10-12; the list grows). The usual ones and their placeholders:
| Template | Placeholder | Grants (summary) |
|---|---|---|
S3ReadPolicy |
BucketName |
s3:GetObject, ListBucket, GetBucketLocation, GetObjectVersion, GetLifecycleConfiguration on the bucket and bucket/* |
S3WritePolicy / S3CrudPolicy |
BucketName |
put objects (+ ACL, lifecycle) / read + write + delete objects |
DynamoDBReadPolicy |
TableName |
GetItem, Scan, Query, BatchGetItem, DescribeTable on the table and table/<name>/index/* |
DynamoDBCrudPolicy |
TableName |
read actions + PutItem, UpdateItem, DeleteItem, BatchWriteItem, ConditionCheckItem |
DynamoDBWritePolicy |
TableName |
PutItem, UpdateItem, BatchWriteItem |
DynamoDBStreamReadPolicy |
TableName, StreamName |
DescribeStream, GetRecords, GetShardIterator, ListStreams |
SQSPollerPolicy |
QueueName |
ReceiveMessage, DeleteMessage(Batch), ChangeMessageVisibility(Batch), GetQueueAttributes |
SQSSendMessagePolicy / SNSPublishMessagePolicy |
QueueName / TopicName |
sqs:SendMessage* / sns:Publish |
LambdaInvokePolicy |
FunctionName |
lambda:InvokeFunction on the function (and its versions and aliases) |
StepFunctionsExecutionPolicy / EventBridgePutEventsPolicy |
StateMachineName / EventBusName |
states:StartExecution / events:PutEvents on that bus |
KMSDecryptPolicy |
KeyId |
kms:Decrypt; KeyId must be a key ID, not an alias |
SSMParameterReadPolicy |
ParameterName |
GetParameter(s), GetParametersByPath; name without a leading slash (SSMParameterWithSlashPrefixReadPolicy for /a/b); non-default KMS key → add KMSDecryptPolicy |
AWSSecretsManagerGetSecretValuePolicy |
SecretArn |
secretsmanager:GetSecretValue on that secret |
KinesisStreamReadPolicy |
StreamName |
describe and read records of the stream |
CloudWatchPutMetricPolicy, VPCAccessPolicy |
none → {} |
cloudwatch:PutMetricData / create, describe, detach and delete network interfaces |
- Policy templates also work in
StateMachine→Policies. Applications in the Serverless Application Repository that rely only on policy templates need no special capability acknowledgment from consumers (§13). - Connectors: embed
Connectorsin the source resource, or declare a standaloneAWS::Serverless::ConnectorwithSourceandDestination(identified byId, or byArn+Typefor resources outside the template) andPermissions(Read,Write). An embedded connector becomes anAWS::Serverless::Connectorwith logical ID<source><connector>; SAM attaches a generated customer managed policy to the source's role, or writes a resource permission (AWS::Lambda::Permission, queue or topic policy) when the source is an event service. Connectors work with plain CloudFormation resources too (for exampleAWS::DynamoDB::Table) and cover supported event connections such as REST API → function (Write). - Example of what a connector composes:
Readfrom a function to a table allowsGetItem,Query,Scan,BatchGetItem,ConditionCheckItemandPartiQLSelecton the table and its indexes. - IAM evaluation,
iam:PassRoleand policy JSON in general →notes/iam-guide.mdandnotes/advanced-identity-guide.md.
Developer angle
Resources:
OrdersTable:
Type: AWS::Serverless::SimpleTable
OrdersQueue:
Type: AWS::SQS::Queue
OrdersFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/orders/
Handler: app.handler
Runtime: python3.13
Policies:
- DynamoDBCrudPolicy: # template with a placeholder
TableName: !Ref OrdersTable
- SQSSendMessagePolicy:
QueueName: !GetAtt OrdersQueue.QueueName
- CloudWatchPutMetricPolicy: {} # no placeholders: {} is mandatory
- AWSXrayWriteOnlyAccess # AWS managed policy by name
- Version: '2012-10-17' # inline policy document
Statement:
- Effect: Allow
Action: ssm:GetParameter
Resource: !Sub 'arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter/orders/*'
ReportFunction:
Type: AWS::Serverless::Function
Connectors: # SAM writes the read policy
ReadOrders: # becomes ReportFunctionReadOrders
Properties:
Destination:
Id: OrdersTable
Permissions: [Read]
Properties:
CodeUri: src/report/
Handler: app.handler
Runtime: python3.13
Traps
- Trap: "A template without parameters can be listed by name only." → Reality: templates need
{}; only managed policy names or ARNs go without it. - Trap: "Pass the alias
alias/orderstoKMSDecryptPolicy." → Reality:KeyIdmust be the key ID. - Trap: "
SSMParameterReadPolicyworks for/orders/db-url." → Reality: for names with a leading slash useSSMParameterWithSlashPrefixReadPolicy. - Trap: "Attach
AmazonDynamoDBFullAccessfor simplicity." → Reality: works, but fails least privilege;DynamoDBReadPolicy/DynamoDBCrudPolicyscope to one table. - Trap: "
DynamoDBCrudPolicylets the function create or delete tables." → Reality: item-level actions plusDescribeTableon one table only.
Practice questions
-
A developer's function polls a specific SQS queue with the SDK, processes the messages and deletes them. The team wants least privilege with the LEAST effort. Which
Policiesentry should the developer add?- A. The AWS managed policy
AmazonSQSFullAccess - B.
SQSSendMessagePolicywithQueueName: !GetAtt JobsQueue.QueueName - C.
SQSPollerPolicywithQueueName: !GetAtt JobsQueue.QueueName - D. An inline policy that allows
sqs:*on*
- A. The AWS managed policy
-
A developer runs
sam build, which fails withMust specify valid parameter values for policy template 'CloudWatchPutMetricPolicy'. The same function also declaresKMSDecryptPolicywithKeyId: alias/payments, and the security team requires access to that key only. Which TWO changes are needed? (Select TWO.)- A. Declare the metric template as
- CloudWatchPutMetricPolicy: {}. - B. Deploy with
CAPABILITY_AUTO_EXPAND. - C. Move the
Policieslist intoGlobals. - D. Replace the templates with the AWS managed policy
PowerUserAccess. - E. Pass the key ID of the payments key, not its alias, to
KMSDecryptPolicy.
- A. Declare the metric template as
Answers
- C.
SQSPollerPolicygrants exactly receive, delete, change visibility and get attributes on the named queue. A and D work but are far broader than needed; B only allows sending. - A, E. Templates without placeholders still need an empty map, and
KMSDecryptPolicybuilds a key ARN from a key ID, so an alias doesn't match. B is unrelated to policy expansion; C is not supported; D breaks least privilege.
6. Creating and building projects with sam init and sam build
Concept
sam initscaffolds a project:template.yaml, function code, anevents/folder with sample events,tests/, a README andsamconfig.toml. Choose an AWS Quick Start template (hello world, scheduled task, data processing, …) or a custom location (Git, Mercurial, HTTPS or local.zip, Cookiecutter).sam buildturns source into deployable artifacts: it installs each function's and layer's dependencies with the runtime's builder (pip, npm, Maven, Gradle, …), compiles where needed, and writes everything to.aws-sam/buildtogether with a rewritten.aws-sam/build/template.yamlthat later commands (local,package,deploy) pick up automatically.
Exam facts
sam initoptions:--name,--runtime(Zip),--package-type Zip|Image,--base-image(Image),--app-template(for examplehello-world),--dependency-manager,--architecture x86_64|arm64,--location,--no-interactive(fails if a required value is missing),--tracing(writesTracing: Active/TracingEnabledglobals),--application-insights.sam build:- Template lookup
template.[yaml|yml]; output.aws-sam/build; optional resource ID builds one function or layer. --use-container/-u: build inside a Lambda-like container image (native or compiled dependencies that must match the Lambda environment); needs a container runtime;--build-imagepicks another build image (error without--use-container).--cachedreuses unchanged artifacts (.aws-sam/cache); it does not notice new versions of unpinned third-party dependencies until a non-cached build.--parallelbuilds functions and layers concurrently.--build-in-source(Node.js withMakefileoresbuild) skips copying to a temporary folder; incompatible with--use-container.- Others:
--manifest(custom requirements or package file),--exclude,--container-env-var,--hook-name terraform.
- Template lookup
- Without
sam build, nothing installs the dependencies: packaging then uploads only what is already in eachCodeUrifolder, and an.aws-sam/buildfolder from an earlier build keeps serving old code until you build again. Metadatabuild methods:BuildMethod: makefile→ custom runtimes (Runtime: provided,provided.al2023) or custom steps; theMakefileinCodeUridefines targetbuild-<LogicalId>and copies results to$(ARTIFACTS_DIR).BuildMethod: esbuild→ Node.js/TypeScript bundling;BuildPropertiesdefaults:Minify: true,Target: es2020,Sourcemap: false; alsoEntryPoints,External,Format.- Image functions:
Metadata→Dockerfile,DockerContext,DockerTag; deploys push to ECR (§7). - Layers:
BuildMethod= a runtime identifier ormakefile(§3).
- A container runtime is needed only for local testing (§10) and container builds: Docker (Docker-runtime alternatives since SAM CLI 1.47.0) or Finch (SAM CLI 1.145.0+, macOS and Linux; Docker wins when both run).
sam validatecheckstemplate.[yaml|yml|json]in the current folder (or the built template right aftersam build);--lintadds cfn-lint rules (configurable with a.cfnlintrcfile).
Developer angle
sam init --no-interactive --name orders-api --runtime python3.13 \
--dependency-manager pip --app-template hello-world --architecture arm64
cd orders-api
sam validate --lint
sam build --cached --parallel # writes .aws-sam/build and .aws-sam/build/template.yaml
sam build --use-container # compiled dependencies built in a Lambda-like container
sam build OrdersFunction # one resource only
An esbuild build declared in the template (image functions use Metadata → Dockerfile, DockerContext, DockerTag instead):
Resources:
CheckoutFunction: # TypeScript bundled with esbuild
Type: AWS::Serverless::Function
Properties:
CodeUri: src/checkout/
Handler: app.handler
Runtime: nodejs22.x
Metadata:
BuildMethod: esbuild
BuildProperties:
Target: es2022 # default es2020; Minify defaults to true
EntryPoints: [app.ts]
Traps
- Trap: "
sam builddeploys the application." → Reality: it only prepares artifacts in.aws-sam;sam deployorsam syncdeploys. - Trap: "Every SAM CLI command needs Docker." → Reality: only local tests and container builds need a container runtime (Docker or Finch).
- Trap: "Dependencies compiled on a laptop always run in Lambda." → Reality: native modules must match the Lambda environment:
sam build --use-container. - Trap: "
--cachedpicks up the newest version of every dependency." → Reality: unpinned dependency upgrades need a non-cached build.
Practice questions
-
A developer's Python function depends on a library with compiled C extensions. Built on the developer's macOS laptop, it passes the unit tests there but fails with import errors after deployment. Which change fixes the problem with the LEAST effort?
- A. Change the function's
Architecturestoarm64. - B. Increase the function's
MemorySizeto 2048 MB. - C. Run
sam deploy --force-upload. - D. Run
sam build --use-containerbefore deploying.
- A. Change the function's
-
A CI job builds a SAM application with 20 functions, and most commits change only one of them. The team wants faster builds without changing the deployment method. Which TWO options should the job add to
sam build? (Select TWO.)- A.
--use-container - B.
--cached - C.
--parallel - D.
--debug - E.
--build-image public.ecr.aws/sam/build-python3.13
- A.
Answers
- D. Building inside a Lambda-like container compiles the extensions for the Lambda environment. A changes the target architecture but not how dependencies are built; B does not fix missing or incompatible binaries; C re-uploads the same broken artifacts.
- B, C. Caching skips unchanged functions and parallel builds use more cores. A adds container start-up time; D only adds logging; E only chooses another build image and requires
--use-container.
7. Packaging and deploying with sam package and sam deploy
Concept
sam deploydoes the whole job: it zips each function and layer and uploads them to S3 (container images go to ECR), rewrites local paths into S3/ECR locations, creates a CloudFormation change set, optionally waits for your confirmation, executes it and streams stack events until the stack settles.sam packageperforms only the upload-and-rewrite step and writes the packaged template, much likeaws cloudformation package; the plain-CLI pairaws cloudformation package+aws cloudformation deploy --capabilities CAPABILITY_IAMalso deploys SAM templates (deployworks through a change set, so noCAPABILITY_AUTO_EXPAND). Packaging separately is useful when a pipeline must store the packaged template as an artifact.- The first deployment usually runs
sam deploy --guided, which asks for stack name, Region, confirmation, IAM role creation, rollback behaviour and a value for every template parameter, then saves the answers tosamconfig.tomlso later runs are a plainsam deploy.
Exam facts
- ⚠️ Changed:
sam deploypackages implicitly, sosam packageis optional. Older material may say you must runsam packagebeforesam deploy. - Without
.aws-sam/build, packaging usestemplate.[yaml|yml]from the working folder; the SAM docs' best practice issam buildbefore every deploy. - Artifact storage:
--s3-bucket <name>or--resolve-s3(a SAM-managed bucket created through theaws-sam-cli-managed-defaultstack), never both (error). A template larger than 51,200 bytes always needs one of them. Image functions:--image-repository,--image-repositories Fn=uri, or--resolve-image-repos(creates ECR repositories and deletes them when their functions are removed).--guidedignores the two--resolve-*flags because it asks instead. --capabilities: IAM resources needCAPABILITY_IAM, IAM resources with custom names needCAPABILITY_NAMED_IAM, nested applications needCAPABILITY_AUTO_EXPAND; missing ones fail withInsufficientCapabilities.--guidedsavescapabilities = "CAPABILITY_IAM"once you allow role creation.- Change-set control:
--confirm-changesetprompts before executing. Prompting is opt-in: without the flag orconfirm_changeset = trueinsamconfig.toml(saved by--guidedwhen you answer Y),sam deployexecutes the change set without asking;--no-confirm-changesetoverrides atruein the file.--no-execute-changesetcreates the change set and exits (review, then rerun without the flag). - Empty change sets:
sam deployexits non-zero by default when nothing changed (--fail-on-empty-changeset); CI pipelines add--no-fail-on-empty-changeset.aws cloudformation deploybehaves the opposite way: zero by default, non-zero only with--fail-on-empty-changeset. - Failure handling:
--on-failure ROLLBACK|DELETE|DO_NOTHING(defaultROLLBACK, applies when a stack fails to create) or--disable-rollback(keep what was created or updated before the error), never both. - Other options:
--stack-name(required, or fromsamconfig),--parameter-overrides ParameterKey=Stage,ParameterValue=prod …,--tags,--role-arn(CloudFormation service role),--kms-key-id(artifact encryption; SSE-S3 otherwise),--force-upload,--signing-profiles(code signing),--notification-arns,--output json(machine-readable progress; not with--guidedor--confirm-changeset). - After deploying:
sam list endpoints|resources|stack-outputs,sam logs(§9),sam traces. Clean-up:sam deleteremoves the stack plus its S3 and ECR artifacts (prompting about an ECR companion stack;--no-promptsdeletes without asking). - For production, use
sam deployor a CI/CD pipeline (§8), neversam sync.
Developer angle
# First deployment: answer the prompts once and save them to samconfig.toml
sam deploy --guided
# Repeatable, non-interactive deployment (CI)
sam build
sam deploy --stack-name orders-prod --resolve-s3 \
--capabilities CAPABILITY_IAM \
--parameter-overrides ParameterKey=Stage,ParameterValue=prod \
--no-confirm-changeset --no-fail-on-empty-changeset
# Review first: create the change set and exit
sam deploy --stack-name orders-prod --resolve-s3 --capabilities CAPABILITY_IAM --no-execute-changeset
# Two-step flow when the packaged template is a pipeline artifact
sam package --s3-bucket my-artifacts-bucket --output-template-file packaged.yaml
sam deploy --template-file packaged.yaml --stack-name orders-prod --capabilities CAPABILITY_IAM
sam list stack-outputs --stack-name orders-prod
sam delete --stack-name orders-dev --no-prompts
Traps
- Trap: "
sam packagemust run before everysam deploy." → Reality:sam deploypackages implicitly. - Trap: "Pass
--s3-bucketand--resolve-s3to be safe." → Reality: combining them is an error. - Trap: "The pipeline fails on commits that only touch documentation, so deployments are broken." → Reality:
sam deployreturns non-zero on an empty change set by default; add--no-fail-on-empty-changeset. - Trap: "
CAPABILITY_IAMcovers roles with custom names." → Reality: custom names needCAPABILITY_NAMED_IAM. - Trap: "Use
--disable-rollbacktogether with--on-failure DELETE." → Reality: pick one of the two.
Practice questions
-
A CI job runs
sam buildandsam deploy --no-confirm-changeseton every commit. Commits that change only the README make the job fail although the stack is healthy. Which change fixes the job?- A. Add
--force-uploadto thesam deploycommand. - B. Add
--no-fail-on-empty-changesetto thesam deploycommand. - C. Add
--disable-rollbackto thesam deploycommand. - D. Replace the
sam deploystep withsam packageand keep the packaged template as an artifact.
- A. Add
-
A team's CI job deploys a SAM application that contains
.zipfunctions and container-image functions. The job must run without prompts, and the team doesn't want to pre-create an S3 bucket or ECR repositories for the artifacts. Which TWO options should the job pass tosam deploy? (Select TWO.)- A.
--guided - B.
--resolve-s3 - C.
--s3-buckettogether with--resolve-s3 - D.
--force-upload - E.
--resolve-image-repos
- A.
Answers
- B. By default
sam deployexits with an error when the change set is empty; the flag turns that into success. A re-uploads artifacts but still produces an empty change set; C changes failure behaviour, not the exit code; D stops deploying altogether. - B, E.
--resolve-s3uses a SAM-managed bucket and--resolve-image-reposcreates the ECR repositories for image functions, both without prompts. A is interactive and ignores both--resolve-*flags; C is an error because the two bucket options are mutually exclusive; D only re-uploads artifacts that already exist.
8. Configuration files and multiple environments
Concept
- The project configuration file stores SAM CLI options so commands become short and repeatable. Options are grouped by environment (a named set such as
default,dev,prod) and by command (deploy,build,sync,local_start_api, … orglobalfor all). - One template serves every environment: environment-specific values live in
samconfigsections (stack name, Region, parameter overrides) and in templateParameters/Conditions;sam deploy --config-env prodselects the production section. - For automated multi-account delivery,
sam pipeline bootstrapcreates the per-stage AWS resources andsam pipeline initgenerates a starter pipeline definition for your CI/CD system.
Exam facts
- Default file:
samconfig.tomlin the project root (next to the template), TOML format;sam initcreates it,sam deploy --guidedand--save-paramswrite to it. YAML is also supported (samconfig.yaml/samconfig.yml). - Lookup order: the
--config-filepath (relative to the template's folder) →samconfig.toml→samconfig.[yaml|yml]. - Structure:
version = 0.1, then tables[<env>.<command>.parameters]; the default environment isdefault, pick another with--config-env <name>. Command names use underscores (local_invoke,local_start_api), keys are long option names with underscores (stack_name,s3_prefix,resolve_s3,confirm_changeset,parameter_overrides). - TOML values: Booleans
true/false, strings in quotes, lists as one space-separated string (capabilities = "CAPABILITY_IAM CAPABILITY_NAMED_IAM"), key-value lists with escaped quotes (parameter_overrides = "Stage=\"prod\""). - Precedence: command-line options > configuration file > template
Parametersdefaults;parameter_overrides(CLI or file) > template defaults; a command-specific section > theglobalsection of the same environment. sam pipeline: starter configurations for AWS CodePipeline, Jenkins, GitLab CI/CD, GitHub Actions and Bitbucket Pipelines, with two deployment stages.sam pipeline bootstrap --stage <name>(run once per stage) creates pipeline permissions (an IAM user with access keys by default, or OIDC with--permissions-provider oidcfor GitHub Actions, GitLab or Bitbucket), a CloudFormation execution role, an S3 artifact bucket and optionally an ECR repository.sam pipeline init --bootstrapdoes both interactively. Pipeline services themselves →notes/cicd-guide.md.- Security angle: prefer the OIDC permissions provider over a pipeline IAM user with long-term keys (if keys are used, rotate them).
Developer angle
samconfig.toml with a development default and a production environment:
version = 0.1
[default.global.parameters]
stack_name = "orders-dev"
region = "eu-west-1"
[default.build.parameters]
cached = true
parallel = true
[default.deploy.parameters]
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true
parameter_overrides = "Stage=\"dev\" LogLevel=\"DEBUG\""
[prod.deploy.parameters]
stack_name = "orders-prod"
region = "eu-west-1"
capabilities = "CAPABILITY_IAM"
confirm_changeset = false
resolve_s3 = true
parameter_overrides = "Stage=\"prod\" LogLevel=\"WARN\""
sam deploy # [default] sections
sam deploy --config-env prod # [prod.*] sections
# Command-line --parameter-overrides take precedence over parameter_overrides in the file
sam deploy --config-env prod \
--parameter-overrides ParameterKey=Stage,ParameterValue=prod ParameterKey=LogLevel,ParameterValue=INFO
sam pipeline bootstrap --stage dev --permissions-provider oidc --oidc-provider github-actions
sam pipeline init # pick CodePipeline, GitHub Actions, GitLab, Jenkins or Bitbucket
In the template, the Stage parameter drives per-environment behaviour through a condition, for example IsProd: !Equals [!Ref Stage, prod] and MemorySize: !If [IsProd, 1024, 256] (conditions and intrinsic functions: notes/cloudformation-guide.md).
Traps
- Trap: "
--config-envselects a different template." → Reality: it selects a section of the configuration file; the template stays the same. - Trap: "
--config-fileis resolved from the shell's current folder." → Reality: relative to the template's location. - Trap: "The global
stack_namebeats the one underdeploy." → Reality: the command-specific entry wins. - Trap: "
sam pipeline bootstrapalways hands long-term access keys to the CI system." → Reality: that's the default, but OIDC is supported and avoids stored keys.
Practice questions
-
A team deploys one SAM template to a development stack and a production stack with different stack names and parameter values. Developers keep typing long
sam deploycommands and occasionally deploy development values to production. Which solution reduces the mistakes with the LEAST effort?- A. Define
devandprodenvironments insamconfig.tomland pass--config-envtosam deploy. - B. Copy the template into
template-dev.yamlandtemplate-prod.yamlwith the values hard-coded in each copy. - C. Add a
Mappingssection keyed by account ID and remove all template parameters. - D. Run
sam deploy --guidedbefore every deployment and retype the values each time.
- A. Define
-
A developer keeps
samconfig.tomlnext totemplate.yaml, setsstack_namein both itsglobalanddeploysections, and sometimes passes options on the command line. Which TWO statements describe how the SAM CLI resolves these settings? (Select TWO.)- A. An option given on the command line overrides the same option in
samconfig.toml. - B. A template parameter's
Defaultoverrides values passed inparameter_overrides. - C. When both exist,
samconfig.yamlis read beforesamconfig.toml. - D. For
sam deploy,stack_nameunder[default.deploy.parameters]overridesstack_nameunder[default.global.parameters]. - E.
--config-filepaths are resolved relative to the folder the command runs from.
- A. An option given on the command line overrides the same option in
Answers
- A. Named environments keep each stage's values in one file and turn the choice into one flag. B duplicates the template and drifts; C removes deploy-time flexibility and still needs per-account values; D keeps the error-prone typing.
- A, D. The CLI beats the file, and a command-specific section beats
global. B is reversed (overrides beat defaults); C is reversed (samconfig.tomlis looked up first); E is wrong because the path is relative to the template.
9. SAM Accelerate and testing in the cloud
Concept
- SAM Accelerate is AWS's name for the SAM CLI tooling that lets you run each edit in a real AWS account almost immediately. Its core command,
sam sync, builds and deploys the stack once and then ships every later change by the fastest available path: code-only edits are pushed with the Lambda, API Gateway and Step Functions APIs and land in seconds without a stack update, while template edits still trigger a CloudFormation deployment. - Because direct API updates make the stack drift from its template,
sam syncis for development stacks only (it asks you to confirm this); production usessam deployor a pipeline.
Exam facts
--stack-nameis required.sam syncwithout--watch(or with--no-watch) builds and performs a one-time CloudFormation deployment (infrastructure + code), likesam build+sam deploy; the default--skip-deploy-sync(below) skips that deployment when the local template matches the deployed one.sam sync --watch: initial deployment, then watches files: code changes → service-API sync; template changes → CloudFormation deployment. Setwatch = truein[default.sync.parameters]to make it the default.--code: sync only code resources through service APIs, never CloudFormation. Supported types (10):AWS::Serverless::Function,AWS::Lambda::Function,AWS::Serverless::LayerVersion,AWS::Lambda::LayerVersion,AWS::Serverless::Api,AWS::ApiGateway::RestApi,AWS::Serverless::HttpApi,AWS::ApiGatewayV2::Api,AWS::Serverless::StateMachine,AWS::StepFunctions::StateMachine.--resource <Type>and--resource-id <LogicalId>(both repeatable, used with--code) narrow the sync; a nested stack resource isNestedStackId/ResourceId.--skip-deploy-syncis the default: the initial CloudFormation deployment is skipped when the local template matches the deployed one, except when the last CloudFormation deployment is 7 or more days old or many function changes make a deployment faster.--no-skip-deploy-syncdeploys every time.--dependency-layeris the default: each function's dependencies move into an auto-created layer (nested stackAwsSamAutoDependencyLayerNestedStack) so code syncs stay small;--use-containerswitches it off.- Default capabilities:
CAPABILITY_NAMED_IAMandCAPABILITY_AUTO_EXPAND.--watch-exclude Fn=fileignores noisy files. - ⚠️ unverified: the current default of
sam sync --express/--no-express(CloudFormation Express mode, infrastructure syncs only). The reference still lists--no-expressbut announces--expressas the default from 2026-09-01; checksam sync --help. Not exam material. sam remote invoke <id>targets Lambda (response streaming detected automatically), SQS (sends a message), Kinesis Data Streams (puts a record) and Step Functions (starts an execution and waits for its output). The ID can be a logical ID with--stack-name, a physical ID or an ARN. Events:--event '<json>',--event-file file.json(or-for stdin),--test-event-name;--parameter InvocationType=DryRunpasses Boto3 parameters;--output json|text.sam remote test-eventgets, puts and deletes shareable Lambda test events stored in the EventBridge schema registry.sam logs:--name/-n(repeatable; nestedStack/Fn),--stack-name,--tail,--filter,--include-traces,--start-time(default 10 minutes ago),--end-time,--cw-log-group; supports functions, REST/HTTP APIs and state machines.sam tracesfetches X-Ray traces (--trace-id,--tail).
Developer angle
# Development loop against a dev stack
sam sync --stack-name orders-dev --watch
# Push one function's code only (seconds, no CloudFormation)
sam sync --stack-name orders-dev --code --resource-id OrdersFunction
# All functions' code, but no APIs or state machines
sam sync --stack-name orders-dev --code --resource AWS::Serverless::Function
# Test what is deployed
sam remote invoke OrdersFunction --stack-name orders-dev --event-file events/order.json
sam remote invoke JobsQueue --stack-name orders-dev --event '{"jobId": "42"}'
sam logs --stack-name orders-dev --name OrdersFunction --tail --filter ERROR
Traps
- Trap: "Use
sam syncto ship to production quickly." → Reality: development stacks only; code syncs cause drift, so production usessam deployor a pipeline. - Trap: "
sam sync --codealso applies my new IAM permissions." → Reality: infrastructure changes need CloudFormation:sam syncwithout--code,--watch, orsam deploy. - Trap: "
--resource-idworks on its own." → Reality: it narrows a--codesync. - Trap: "Every
sam syncrun redeploys the stack." → Reality:--skip-deploy-sync(default) skips an unchanged template, but not after 7 days. - Trap: "
sam remote invokeruns the function in local Docker." → Reality: it calls the deployed resource in AWS.
Practice questions
-
A developer iterates on a function's handler code in a development stack and wants every saved change to run in the AWS account within seconds, without typing a deploy command each time. Which command should the developer use?
- A.
sam deploy --no-confirm-changesetafter every save - B.
sam local start-api --warm-containers EAGER - C.
sam sync --stack-name orders-dev --watch - D.
sam build --cached --parallel
- A.
-
A developer has used
sam sync --codeagainst a development stack for a week. The CloudFormation stack no longer matches the deployed function code, and a new IAM permission added to the template never took effect. Which TWO statements are correct? (Select TWO.)- A.
--codeupdates IAM roles together with the function code. - B.
--codeupdates code through service APIs and bypasses CloudFormation, which causes drift. - C. Enabling termination protection on the stack applies the pending permission.
- D. Adding
--no-dependency-layermakes--codeapply IAM changes. - E. Running
sam deploy(orsam syncwithout--code) applies the template's infrastructure changes.
- A.
Answers
- C.
--watchkeeps the CLI running and syncs code changes through service APIs in seconds. A works but needs a full change-set deployment per save; B runs locally, not in the account; D only builds. - B, E. Code syncs bypass CloudFormation, so only a CloudFormation deployment applies the permission. A is false; C only blocks deletion; D only changes how dependencies are packaged.
10. Local testing with sam local and generated events
Concept
- The SAM CLI runs functions in local containers that mimic the Lambda runtime, so you can test before deploying:
sam local invoke(runs a function for a single event and returns its result),sam local start-api(serves the template's API routes on your machine, emulating API Gateway),sam local start-lambda(answers LambdaInvokecalls from the CLI or an SDK) andsam local generate-event(prints realistic test events for services such as S3, SQS or API Gateway). - Local is not the cloud: only the function code and the API front end are emulated. Calls to DynamoDB, S3 and other services go to real AWS endpoints with your local credentials (or to separate local tools), and IAM permissions between resources are not checked.
Exam facts
- All local runs need a container runtime: Docker (or a Docker-runtime alternative, SAM CLI 1.47.0+) or Finch (SAM CLI 1.145.0+, macOS and Linux).
- Local commands use
.aws-sam/build/template.[yaml|yml]when it exists, otherwise the template in the current folder; after a build, code changes appear only after rebuilding. sam local invoke [LogicalId](ID required when the template has several functions; nested:Stack/Fn):--event/-e file.json, or-e -to read the event from stdin;--no-eventsends an empty event.--env-vars env.json(or.env): JSON with aParametersobject for all functions and per-function objects keyed by logical ID; function-specific values win.--profile/--region: the credentials and Region the local code uses when it calls AWS;--parameter-overrides;--debug-port/-dfor a debugger;--docker-networkto reach other local containers;--runtimeoverrides the runtime;--skip-pull-image.- Function logs go to stderr, the result to stdout. AWS advises against running untrusted code with local invoke.
sam local generate-event <service> <event> [options]prints JSON only: for examples3 put --bucket b --key k,s3 delete,apigateway http-api-proxy;sam local generate-event --helplists every service. Pipe it intosam local invoke -e -or save it underevents/.sam local start-api: defaulthttp://127.0.0.1:3000(--port,--host); a new container per request unless--warm-containers EAGER|LAZY;--env-vars,--static-dir,--debug-port; Lambda authorizers run locally (SAM CLI 1.80.0+, fidelity not guaranteed).- ⚠️ Changed:
start-apipicks up code changes automatically only for interpreted runtimes when no.aws-sambuild exists; after asam build, runsam buildagain to pick up edits, and restartstart-apiafter template changes. Older material may say changes to functions are always reloaded automatically. sam local start-lambda: defaulthttp://127.0.0.1:3001; call it withaws lambda invoke --endpoint-url http://127.0.0.1:3001 --no-verify-sslor an SDK client whose endpoint points there; ideal for automated integration tests.- ⚠️ Changed: the SAM CLI emulates Lambda functions and API Gateway locally; DynamoDB needs DynamoDB local (a JAR, Docker image or Maven dependency) or a real development table. Older material may say SAM runs DynamoDB locally.
Developer angle
# S3 event for a specific bucket and key, piped straight into the function
sam local generate-event s3 put --bucket uploads-dev --key photos/cat.jpg \
| sam local invoke ThumbnailFunction -e -
# Keep a reusable event and override environment variables
sam local generate-event apigateway http-api-proxy > events/http.json
sam local invoke CreateOrderFunction -e events/http.json --env-vars env.json --profile dev
# Local API and a local Lambda endpoint for SDK tests
sam local start-api --port 3000 --warm-containers EAGER
sam local start-lambda --port 3001
aws lambda invoke --function-name CreateOrderFunction \
--endpoint-url http://127.0.0.1:3001 --no-verify-ssl out.json
env.json (global values plus a per-function override, which wins for that function):
{"Parameters": {"STAGE": "local", "TABLE_NAME": "orders-dev"},
"CreateOrderFunction": {"TABLE_NAME": "orders-local-test"}}
In SDK-based tests, create the Lambda client with endpoint_url="http://127.0.0.1:3001" (AWS's boto3 example also disables SSL, request signing and retries) and call invoke as usual.
Traps
- Trap: "
sam local invokeruns with the function's execution role." → Reality: it uses your local credentials (--profile) when the code calls AWS. - Trap: "I rebuilt once, so later edits show up automatically." → Reality: with a
.aws-sambuild, every code change needssam buildagain. - Trap: "
start-lambdaserves my API routes." → Reality:start-apiserves HTTP routes;start-lambdaimplements the LambdaInvokeAPI. - Trap: "The SAM CLI emulates DynamoDB." → Reality: use DynamoDB local or a real development table.
- Trap: "A passing local test proves the IAM policy is right." → Reality: permissions are only exercised in the cloud.
Practice questions
-
A developer wants to test locally how a function handles an S3 upload notification for a specific bucket and object key, without uploading anything to AWS. Which approach requires the LEAST effort?
- A. Upload a test object to the development bucket and then read the function's logs with
sam logs --tail. - B. Run
sam local start-apiand send the object to the local endpoint with an HTTPPOSTrequest. - C. Run
sam remote invoke ThumbnailFunctionwith an empty event. - D.
sam local generate-event s3 put --bucket uploads-dev --key photos/cat.jpg | sam local invoke ThumbnailFunction -e -
- A. Upload a test object to the development bucket and then read the function's logs with
-
A CI job must run integration tests that call the Lambda
InvokeAPI through the AWS SDK against functions running locally, before anything is deployed. Which TWO steps are required? (Select TWO.)- A. Start
sam local start-lambdain the job. - B. Start
sam local start-apiand send the SDK calls to port 3000. - C. Point the SDK's Lambda client endpoint to
http://127.0.0.1:3001. - D. Deploy the stack with
sam syncbefore the tests run. - E. Set the
AWS_LAMBDA_FUNCTION_NAMEenvironment variable in the test process.
- A. Start
Answers
- D.
generate-eventbuilds a realistic S3 payload with the given bucket and key, and-e -feeds it to the local invocation. A and C run in the cloud; B serves API routes, not S3 notifications. - A, C.
start-lambdaexposes a localInvokeendpoint (default port 3001), and the SDK client must target it. B emulates API Gateway routes, not the Lambda API; D deploys, which the requirement excludes; E is a variable that the Lambda runtime sets inside functions and does not redirect SDK calls.
11. Automatic versions and aliases with AutoPublishAlias
Concept
AutoPublishAlias: livetells SAM to publish a new version of the function whenever a deployment changes something that matters and to point an alias with that name at it. Without it, everything invokes$LATEST.- Event sources that SAM generates are wired to the alias, and so is a function URL, so a deployment moves all callers to the new version at once (or gradually with
DeploymentPreference, §12). - The alias is also where version-level features attach:
ProvisionedConcurrencyConfig, SnapStart snapshots of published versions, and CodeDeploy traffic shifting. Version and alias mechanics themselves →notes/lambda-guide.md.
Exam facts
- Generated resources:
AWS::Lambda::Versionwith logical ID<fn>Version<hash>(referenceMyFunction.Version) andAWS::Lambda::Aliaswith logical ID<fn>Alias<alias>(referenceMyFunction.Alias), for exampleOrdersFunctionAliaslive. - A new version is published when the code changes (
CodeUri,ImageUri,InlineCode→Code) or whenEnvironment,MemorySizeorSnapStartchange.AutoPublishAliasAllProperties: true(defaultfalse, needsAutoPublishAlias) publishes on any property change, for exampleTimeout. - SAM compares the template text, not resolved values: if only a stack parameter's value changes (for example an environment variable set to
!Ref LogLevel), no version is published and only$LATESTchanges, even withAutoPublishAliasAllProperties: true. Fix: listAWS::LanguageExtensionsbeforeAWS::Serverless-2016-10-31so references are resolved first. SAR applications can't use that transform: put a literal value in the template instead. AutoPublishCodeSha256: a value you change to force a new version when new code was uploaded to the same S3 key with an unchangedCodeUri; it takes precedence overAutoPublishAliasAllProperties.ProvisionedConcurrencyConfigis accepted only withAutoPublishAlias(it is set on the alias); otherwise the transform reports an error.SnapStart: ApplyOn: PublishedVersionsworks on published versions, so pair it withAutoPublishAlias.VersionDeletionPolicy(Delete,Retain,Snapshot) sets theDeletionPolicyof generated versions;VersionDescriptionsets their description.AutoPublishAliascan be set inGlobalsfor all functions.AWS::Serverless::StateMachinehas its ownAutoPublishAliasfor state machine versions.
Developer angle
Parameters:
LogLevel:
Type: String
Default: INFO
Resources:
OrdersFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/orders/
Handler: app.handler
Runtime: python3.13
AutoPublishAlias: live
AutoPublishAliasAllProperties: true # a Timeout change also publishes a version
ProvisionedConcurrencyConfig:
ProvisionedConcurrentExecutions: 5 # configured on the live alias
Environment:
Variables:
LOG_LEVEL: !Ref LogLevel # parameter-only changes: see the trap below
Outputs:
LiveAliasArn:
Value: !Ref OrdersFunction.Alias
CurrentVersionArn:
Value: !Ref OrdersFunction.Version
Check what is live with aws lambda get-alias --function-name <physical-name> --name live and aws lambda list-versions-by-function --function-name <physical-name>.
Traps
- Trap: "Changing a parameter value that feeds an environment variable publishes a new version." → Reality: the template text is unchanged, so only
$LATESTchanges; addAWS::LanguageExtensionsfirst inTransform. - Trap: "A
Timeoutchange publishes a version by default." → Reality: only withAutoPublishAliasAllProperties: true. - Trap: "Configure
ProvisionedConcurrencyConfigwithout an alias." → Reality: it requiresAutoPublishAlias. - Trap: "Callers that use the unqualified function name get the alias." → Reality: an unqualified invoke hits
$LATEST; SAM-generated triggers and URLs use the alias, your own callers must use the alias ARN. - Trap: "
AutoPublishAliasalone shifts traffic gradually." → Reality: alone it moves the alias at once; gradual needsDeploymentPreference.
Practice questions
-
A team's function sets
AutoPublishAlias: live, and itsLOG_LEVELenvironment variable is!Ref LogLevel. When the team deploys with a newLogLevelvalue, thelivealias keeps serving the old setting. Which change fixes this with the LEAST effort?- A. Set
AutoPublishAliasAllProperties: trueon the function. - B. Add
AWS::LanguageExtensionsbefore the serverless transform inTransform. - C. Delete the
livealias before each deployment and let the next deployment recreate it. - D. Deploy with
sam deploy --force-upload.
- A. Set
-
A developer needs provisioned concurrency on the version of a function that receives production traffic, and the function URL must always reach the released version, not
$LATEST. Which TWO template settings meet these requirements? (Select TWO.)- A. Set
ProvisionedConcurrencyConfigon$LATESTwithout an alias. - B. Set
ReservedConcurrentExecutionsto pre-warm execution environments. - C. Set
FunctionUrlConfigwithInvokeMode: RESPONSE_STREAM. - D. Set
AutoPublishAliason the function. - E. Set
ProvisionedConcurrencyConfigon the function, which SAM applies to the alias.
- A. Set
Answers
- B. With language extensions, references resolve before SAM computes the version hash, so the parameter change publishes a version and moves the alias. A doesn't help: parameter-only changes don't publish even with that flag; C causes downtime and is manual; D re-uploads artifacts but leaves the template unchanged.
- D, E. The alias exists only with
AutoPublishAlias; provisioned concurrency is then set on it, and the function URL follows the alias. A is rejected (and$LATESTcan't have provisioned concurrency); B caps or reserves capacity but doesn't pre-initialize; C changes the response mode, not the target version.
12. Traffic shifting with DeploymentPreference hooks and alarms
Concept
DeploymentPreferenceturns every deployment that publishes a new version into a CodeDeploy deployment for Lambda: CodeDeploy shifts the alias's traffic from the old version to the new one (two steps, equal steps or all at once), runs optional test functions before and after the shift, watches CloudWatch alarms and moves the alias back automatically if anything goes wrong.- CodeDeploy for EC2 and ECS, appspec files and deployment configurations in general →
notes/cicd-guide.md; manual alias weights →notes/lambda-guide.md; API Gateway stage canaries are a different mechanism →notes/api-gateway-guide.md.
Exam facts
DeploymentPreferencerequiresAutoPublishAlias(error otherwise).- Generated resources:
AWS::CodeDeploy::ApplicationServerlessDeploymentApplication(one per stack),AWS::CodeDeploy::DeploymentGroup<fn>DeploymentGroup(one per function), and, unlessDeploymentPreference.Roleis given, the IAM roleCodeDeployServiceRolewith the AWS managed policyAWSCodeDeployRoleForLambda. - Predefined
Typevalues (9):Canary10Percent5Minutes,Canary10Percent10Minutes,Canary10Percent15Minutes,Canary10Percent30Minutes,Linear10PercentEvery1Minute,Linear10PercentEvery2Minutes,Linear10PercentEvery3Minutes,Linear10PercentEvery10Minutes,AllAtOnce. SAM maps them to CodeDeploy'sCodeDeployDefault.Lambda<Type>configurations; the name of a custom CodeDeploy deployment configuration is accepted too.- Canary: 10 % first, the other 90 % after the interval (two increments) · Linear: 10 % more per interval until 100 % · AllAtOnce: all traffic at once (hooks still run).
Alarms: CloudWatch alarms watched during the deployment (Fn::Ifallowed). Any alarm inALARMstops the deployment and rolls back. The deployment group's automatic rollback events areDEPLOYMENT_FAILURE,DEPLOYMENT_STOP_ON_ALARMandDEPLOYMENT_STOP_ON_REQUEST. Lambda metric dimensions:FunctionName(all versions),Resource(one version or alias),ExecutedVersion(compare two versions behind a weighted alias).Hooks:PreTrafficruns before any traffic shifts (CodeDeployBeforeAllowTraffic),PostTrafficafter all traffic has shifted (AfterAllowTraffic). SAM wires them through the alias's CloudFormationUpdatePolicyCodeDeployLambdaAliasUpdate.- A hook receives
DeploymentIdandLifecycleEventHookExecutionIdin its event and must callPutLifecycleEventHookExecutionStatuswithSucceededorFailed. If CodeDeploy hears nothing within 1 hour, the deployment fails. The hook's role needscodedeploy:PutLifecycleEventHookExecutionStatus(pluslambda:InvokeFunctionon the new version if it tests it). - With the generated
CodeDeployServiceRole, CodeDeploy may invoke only functions whose names start withCodeDeployHook_(AWSCodeDeployRoleForLambdaallowslambda:InvokeFunctiononfunction:CodeDeployHook_*), so name hook functions accordingly or supply your ownRole. - A failed hook or alarm fails the CodeDeploy deployment, which reports the failure to CloudFormation: the alias returns to the old version and the stack update rolls back.
- First gradual deployment: CodeDeploy needs an existing version to shift from, so deploy once with
AutoPublishAliasonly, then addDeploymentPreference. - Other properties:
Enabled(defaulttrue),PassthroughCondition(pass the function'sConditionto the generated CodeDeploy resources),TriggerConfigurations(SNS notifications about deployment events). AWS::Serverless::StateMachinealso acceptsAutoPublishAlias+DeploymentPreference, but that is a Step Functions alias deployment (AWS::StepFunctions::StateMachineAlias), not CodeDeploy (notes/other-services-guide.md).
Developer angle
Resources:
OrdersFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src/orders/
Handler: app.handler
Runtime: python3.13
AutoPublishAlias: live
DeploymentPreference:
Type: Canary10Percent5Minutes
Alarms:
- !Ref OrdersErrorsAlarm
Hooks:
PreTraffic: !Ref PreTrafficHook # a PostTraffic hook follows the same pattern
OrdersErrorsAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
Namespace: AWS/Lambda
MetricName: Errors
Dimensions: [{Name: FunctionName, Value: !Ref OrdersFunction}]
Statistic: Sum
Period: 60
EvaluationPeriods: 1
Threshold: 0
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
PreTrafficHook:
Type: AWS::Serverless::Function
Properties:
FunctionName: CodeDeployHook_ordersPreTraffic # prefix required by the generated service role
CodeUri: src/hooks/
Handler: pre_traffic.handler
Runtime: python3.13
Timeout: 300
Environment:
Variables:
TARGET_VERSION_ARN: !Ref OrdersFunction.Version
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action: codedeploy:PutLifecycleEventHookExecutionStatus
Resource: !Sub 'arn:${AWS::Partition}:codedeploy:${AWS::Region}:${AWS::AccountId}:deploymentgroup:${ServerlessDeploymentApplication}/*'
- LambdaInvokePolicy:
FunctionName: !Ref OrdersFunction
The hook tests the new version, then reports the result (no report within 1 hour = failed deployment):
import os
import boto3
codedeploy = boto3.client("codedeploy")
lambda_client = boto3.client("lambda")
def handler(event, context):
result = lambda_client.invoke(FunctionName=os.environ["TARGET_VERSION_ARN"], Payload=b'{"healthCheck": true}')
status = "Failed" if result.get("FunctionError") else "Succeeded"
codedeploy.put_lifecycle_event_hook_execution_status(
deploymentId=event["DeploymentId"],
lifecycleEventHookExecutionId=event["LifecycleEventHookExecutionId"],
status=status,
)
Traps
- Trap: "Add
DeploymentPreferencewithout an alias." → Reality: it requiresAutoPublishAlias. - Trap: "Name the hook anything." → Reality: with the generated service role, hook names must start with
CodeDeployHook_(or provideDeploymentPreference.Role). - Trap: "The hook passes because its tests passed." → Reality: it must call
PutLifecycleEventHookExecutionStatus; silence fails the deployment after 1 hour. - Trap: "
Canary10Percent10Minutesmoves 10 % every 10 minutes." → Reality: that'sLinear10PercentEvery10Minutes; the canary moves 10 % once, then the rest after 10 minutes. - Trap: "The very first deployment already shifts traffic gradually." → Reality: there is no previous version; deploy with the alias first.
Practice questions
-
A team wants each release of a function to receive 10 % of production traffic for 5 minutes and then all traffic, with automatic rollback if the function's error alarm fires. Which solution requires the LEAST operational overhead?
- A. Set
AutoPublishAliasand aDeploymentPreferencewithType: Canary10Percent5Minutesand the alarm underAlarms. - B. Set
AutoPublishAliasand aDeploymentPreferencewithType: Linear10PercentEvery1Minuteand the alarm underAlarms. - C. Configure a canary on the API Gateway stage with 10 % of traffic and promote it after 5 minutes.
- D. Run a scheduled script that calls
aws lambda update-aliaswith a routing configuration and checks the alarm.
- A. Set
-
A team's gradual deployments of a function keep failing about one hour after they start. The pre-traffic hook function's logs show that all its tests passed. Which TWO actions fix the problem? (Select TWO.)
- A. Raise the hook function's timeout to 15 minutes.
- B. Make the hook call
PutLifecycleEventHookExecutionStatuswith theDeploymentIdandLifecycleEventHookExecutionIdfrom its event. - C. Grant the hook's execution role
codedeploy:PutLifecycleEventHookExecutionStatus. - D. Change the deployment
TypetoAllAtOnce. - E. Deploy the stack with
CAPABILITY_AUTO_EXPAND.
Answers
- A. The predefined canary shifts 10 %, waits 5 minutes, shifts the rest, and rolls back on alarm. B shifts 10 % per minute (ten steps), not 10 % then everything; C splits API stage traffic and needs manual promotion; D is custom code to build and run.
- B, C. CodeDeploy waits for the hook's status report and fails the deployment after an hour without one; the hook must make the call and be allowed to. A doesn't send a status; D still runs the hooks; E is unrelated to hooks.
13. Serverless Application Repository and nested applications
Concept
- The AWS Serverless Application Repository (SAR) stores serverless applications (a SAM template plus its packaged artifacts) so that others can find, configure and deploy them. Publishers keep an application private (the default), share it with chosen accounts or their AWS Organization, or make it public.
- Consumers deploy an application from the Lambda console, the CLI or an SDK (SAR creates a CloudFormation change set in their account), or nest it inside their own template with
AWS::Serverless::Application. - Nested applications (from SAR, S3 or a local path) are the SAM way to reuse common components: each becomes a nested CloudFormation stack.
Exam facts
- Publishing with the SAM CLI: (1) add
Metadata→AWS::ServerlessRepo::Application(Name,Description,Author,SpdxLicenseId,LicenseUrl,ReadmeUrl,Labels,HomePageUrl,SemanticVersion,SourceCodeUrl); (2)sam package --output-template-file packaged.yaml --s3-bucket <bucket>uploads code, license and readme, and the bucket policy must letserverlessrepo.amazonaws.comcalls3:GetObjectonbucket/*(scope it withaws:SourceAccount); (3)sam publish --template packaged.yaml --region <region>. - New version: same
Name, newSemanticVersion. Nested applications must be published before the parent. - Visibility: private (default; only the owning account, same Region), privately shared (listed AWS accounts or an Organization; same Region; principals are whole accounts, never individual IAM users), public (everyone, all Regions; needs
SemanticVersionandLicenseUrl). - Sharing with the CLI:
aws serverlessrepo put-application-policy --statements Principals=<account-id>,Actions=Deploy; for an Organization addPrincipalOrgIDs=<org-id>and includeUnshareApplication;--statements '[]'makes it private again;get-application-policyshows the policy; the Organization's management account can rununshare-applicationon any application shared with it. - Application actions:
GetApplication,CreateCloudFormationChangeSet(deploy only),CreateCloudFormationTemplate,ListApplicationVersions,ListApplicationDependencies,SearchApplications;Deploygrants all of them. To let specific accounts nest an application:GetApplication+CreateCloudFormationTemplate. - Consumer acknowledgments (4):
CAPABILITY_IAM/CAPABILITY_NAMED_IAM(IAM resources / custom names),CAPABILITY_RESOURCE_POLICY(for exampleAWS::Lambda::Permission, bucket, queue, topic or event bus policies),CAPABILITY_AUTO_EXPAND(nested applications).aws serverlessrepo get-applicationreturnsrequiredCapabilities. Applications that rely only on SAM policy templates need no special acknowledgment. - SAR refuses to publish applications that attach
AWSLambda_FullAccessto functions or grantiam:AttachRolePolicy,iam:PutRolePolicyoriam:*on all resources in inline policies. It accepts only theAWS::Serverless-2016-10-31transform (templates withAWS::LanguageExtensionsare rejected). AWS::Serverless::Application:Location={ApplicationId, SemanticVersion}(SAR) or a template URL / local path (local paths go throughsam packageorsam deploy);Parameters,NotificationARNs,Tags,TimeoutInMinutes. It becomes anAWS::CloudFormation::Stack;!GetAtt MyApp.Outputs.<OutputName>reads its outputs; SAR nesting adds tagsserverlessrepo:applicationIdandserverlessrepo:semanticVersion.- Limits: up to 200 nested applications per application and 60 parameters per nested application. A parent inherits its nested applications' sharing restrictions. Deploying needs
CAPABILITY_AUTO_EXPAND.
Developer angle
Publisher side:
Metadata:
AWS::ServerlessRepo::Application:
Name: image-resizer
Description: Resizes images uploaded to S3
Author: platform-team
SpdxLicenseId: Apache-2.0
LicenseUrl: LICENSE.txt # needed (with SemanticVersion) to go public
ReadmeUrl: README.md
Labels: ['images', 's3']
SemanticVersion: 1.2.0
SourceCodeUrl: https://github.com/example/image-resizer
sam package --s3-bucket sar-artifacts-bucket --output-template-file packaged.yaml
sam publish --template packaged.yaml --region eu-west-1
# Share with every account in the organization (keep the right to unshare)
aws serverlessrepo put-application-policy --region eu-west-1 \
--application-id arn:aws:serverlessrepo:eu-west-1:111122223333:applications/image-resizer \
--statements Principals=*,PrincipalOrgIDs=o-a1b2c3d4e5,Actions=Deploy,UnshareApplication
Consumer side, nesting the shared application:
Resources:
Resizer:
Type: AWS::Serverless::Application
Properties:
Location:
ApplicationId: arn:aws:serverlessrepo:eu-west-1:111122223333:applications/image-resizer
SemanticVersion: 1.2.0
Parameters:
MaxWidth: '1024'
Outputs:
ResizerQueueUrl:
Value: !GetAtt Resizer.Outputs.QueueUrl
sam deploy --stack-name media-prod --resolve-s3 --capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND
# Or deploy the application on its own through SAR: create the change set, then execute it
CHANGE_SET_ID=$(aws serverlessrepo create-cloud-formation-change-set \
--application-id arn:aws:serverlessrepo:eu-west-1:111122223333:applications/image-resizer \
--semantic-version 1.2.0 --stack-name image-resizer \
--capabilities CAPABILITY_IAM CAPABILITY_RESOURCE_POLICY \
--query ChangeSetId --output text)
aws cloudformation execute-change-set --change-set-name "$CHANGE_SET_ID"
Traps
- Trap: "Make an application public without a license." → Reality: public sharing needs
SemanticVersionandLicenseUrl. - Trap: "Share the application with one IAM user in another account." → Reality: principals are AWS accounts (or an Organization), not individual users.
- Trap: "A privately shared application can be deployed in any Region." → Reality: private and privately shared applications stay in their Region; public ones are available in all Regions.
- Trap: "
CAPABILITY_RESOURCE_POLICYis a normal CloudFormation capability." → Reality: it's a SAR acknowledgment for resource policies. - Trap: "Share with the organization using only
Actions=Deploy." → Reality: organization sharing must also includeUnshareApplication.
Practice questions
-
A company wants every account in its AWS Organization, and no one else, to deploy an internal application published in the Serverless Application Repository. Which solution meets the requirement with the LEAST effort?
- A. Make the application public and tell the teams its name.
- B. Add a bucket policy that allows the Organization to read the packaged artifacts in S3.
- C. Call
put-application-policywith the organization ID inPrincipalOrgIDsandActions=Deploy,UnshareApplication. - D. Call
put-application-policyseparately for every member account, each time with that account's ID as the principal.
-
A consumer calls
aws serverlessrepo create-cloud-formation-change-setfor a shared application. ItsrequiredCapabilitiesshow that the template createsAWS::Lambda::Permissionresources and contains a nested application but no IAM resources, and the call is rejected because those capabilities were not acknowledged. Which TWO changes let the deployment proceed? (Select TWO.)- A. Add
CAPABILITY_RESOURCE_POLICYto--capabilities. - B. Add
CAPABILITY_NAMED_IAMto--capabilities. - C. Retry the deployment with
aws cloudformation deploy --disable-rollback. - D. Add
CAPABILITY_AUTO_EXPANDto--capabilities. - E. Ask the publisher to add a bucket policy that grants
serverlessrepo.amazonaws.comread access.
- A. Add
Answers
- C. An application policy with the Organization ID shares with all member accounts at once (and must include
UnshareApplication). A exposes it to everyone; B doesn't grant deploy permission on the application; D works but must be repeated for every current and future account. - A, D. Lambda permissions are resource policies (
CAPABILITY_RESOURCE_POLICY) and nested applications needCAPABILITY_AUTO_EXPAND. B covers IAM resources with custom names, which this template doesn't create; C changes failure handling and acknowledges nothing; E is a publisher-side publishing requirement.
Quick decision rules
Templates, resources and permissions (§1–§5)
- If you see "turn a CloudFormation template into a SAM template", think
Transform: AWS::Serverless-2016-10-31at the top level. - If you see
create-stackfailing on a SAM template withInsufficientCapabilities, thinkCAPABILITY_AUTO_EXPAND(plusCAPABILITY_IAMfor generated roles), or deploy through a change set. - If you see a function override of a global map or list, think map merged (resource key wins) and list prepended with the global entries.
- If you see "only
Prodstage wanted butStageappears", thinkOpenApiVersionunderGlobals→Api. - If you see "table with a sort key or index", think
AWS::DynamoDB::Table, notSimpleTable. - If you see "least privilege to one table, bucket or queue with the least effort", think the matching policy template (
DynamoDBReadPolicy,S3ReadPolicy,SQSPollerPolicy, …) or a connector. - If you see
Must specify valid parameter values for policy template, think the missing{}. - If you see
RoleandPoliciestogether with missing permissions, thinkPoliciesis ignored whenRoleis set. - If you see an S3 event on a bucket from another stack, think the bucket must be declared in the same template.
Build, deploy, configure and test (§6–§10)
- If you see native dependencies that break after deployment, think
sam build --use-container. - If you see a CI job failing on an empty change set, think
sam deploy --no-fail-on-empty-changeset. - If you see dev and prod from one template with different values, think
samconfig.tomlenvironments +--config-env. - If you see "seconds-fast feedback in a development account", think
sam sync --watch(or--codefor code only). - If you see stack drift after code syncs or an IAM change that never applied, think
sam sync --codebypassed CloudFormation: runsam deploy. - If you see "test with a realistic S3, API Gateway or queue event locally", think
sam local generate-event … | sam local invoke -e -. - If you see "integration tests call
Invokethrough the SDK locally", thinksam local start-lambdaon port 3001. - If you see a pipeline that should not store long-term keys, think
sam pipeline bootstrap --permissions-provider oidc.
Releases and sharing (§11–§13)
- 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; "10 % more every N minutes", thinkLinear10PercentEvery<N>Minute(s). - If you see "roll back automatically on errors during a release", think
DeploymentPreferenceAlarms. - If you see "run tests before or after traffic shifts", think
PreTraffic/PostTraffichooks that callPutLifecycleEventHookExecutionStatus. - If you see a hook that CodeDeploy can't invoke, think the
CodeDeployHook_name prefix (or a customDeploymentPreference.Role). - If you see "share a serverless app with other accounts or the organization", think SAR
put-application-policy(Organization:PrincipalOrgIDs+UnshareApplication). - If you see "reuse a component across SAM templates", think
AWS::Serverless::Application+CAPABILITY_AUTO_EXPAND.
Changed vs older material
Learn the Current column; older practice material may still show the Older material may say value. These rows will move to notes/current-facts.md once you confirm them during /ingest.
| Topic | Older material may say | Current (verified 2026-10-12) | Source |
|---|---|---|---|
| §1 · Template format | All SAM configuration is YAML | SAM templates can be YAML or JSON | AWS docs |
| §1 · SAM resource types | Only Function, Api and SimpleTable (or the original seven types) |
13 types: Api, Application, CapacityProvider, Connector, Function, GraphQLApi, HttpApi, LayerVersion, MicrovmImage, NetworkConnector, SimpleTable, StateMachine, WebSocketApi |
AWS docs |
| §2 · Scheduled functions | Use the Schedule event (EventBridge / CloudWatch Events rule) |
AWS recommends ScheduleV2 (EventBridge Scheduler); Schedule still creates an AWS::Events::Rule |
AWS docs |
| §4 · Globals resource types | Function, Api, HttpApi, SimpleTable |
8 types: those plus StateMachine, CapacityProvider, MicrovmImage, NetworkConnector (the anatomy page lists six) |
AWS docs |
| §7 · Packaging before deployment | sam package must run before sam deploy |
sam deploy packages implicitly; sam package is optional (packaged template as an artifact) |
AWS docs |
| §10 · Local emulation scope | SAM runs Lambda, API Gateway and DynamoDB locally | SAM CLI emulates Lambda and API Gateway; DynamoDB needs DynamoDB local (JAR, Docker image or Maven) or a real table | AWS docs · SAM testing |
§10 · sam local start-api reloads |
Changes to functions are always reloaded automatically | Automatic only without an .aws-sam build (interpreted runtimes); after sam build, rebuild to pick up changes; template changes need a restart |
AWS docs |