DVA-C02 Cheat Sheet
Development with AWS Services
Application Code on AWS
Read full chapterCheat sheet
Sharp facts the exam loves — scan these before test day.
- Loose coupling means putting a managed buffer between caller and worker
Two components are tightly coupled when the caller invokes the worker directly and blocks for the answer, so a slow or down worker fails the caller too. The fix is to insert a managed intermediary (an Amazon SQS queue, an Amazon SNS topic, or an Amazon EventBridge bus) so the producer hands off and returns immediately while the consumer works on its own schedule. Decoupled, the two scale, retry, and fail independently, and a worker outage shows up as queue depth rather than caller errors.
Trap Adding more compute capacity to the worker to stop a slow worker from failing the caller, when the real fix is to decouple them with a managed buffer so the caller no longer blocks on the worker at all.
- Asynchronous handoff changes the contract: the caller no longer learns the outcome inline
A synchronous call blocks until a result returns, like an API Gateway request waiting on a Lambda response; an asynchronous call hands the work off and returns before it finishes, like publishing to SNS, enqueuing to SQS, or invoking Lambda with the
Eventinvocation type. Asynchronous is what buys loose coupling, but because the caller gets no inline result, failures surface later through retries, dead-letter queues, or destinations instead of as an immediate error.Trap Expecting an asynchronous (Event) invocation to return the function's result to the caller, when it returns immediately after accepting the request and the outcome surfaces only later through retries, a DLQ, or destinations.
- Push shared state out of the compute tier so the compute stays stateless and disposable
A stateless component keeps no client-specific data between requests, so any instance (or any Lambda execution environment) can serve any request, which is what lets a fleet scale horizontally and lets a failed unit's work be retried elsewhere. A stateful component remembers prior requests locally, breaking horizontal scaling because a follow-up must reach the same instance. Move shared state into a managed store such as DynamoDB, ElastiCache, or an SQS queue; statelessness is also what makes a retry safe to repeat.
Trap Storing session or client-specific state in a Lambda function's /tmp or in module-level globals to persist it between requests, when the execution environment is reused unpredictably and never guaranteed, so shared state belongs in DynamoDB or ElastiCache.
- Pick the messaging service by who reads each message
The deciding question across SQS, SNS, and EventBridge is who consumes a given message. SQS delivers each message to exactly one consumer from a competing pool, so it suits work distribution and load leveling. SNS pushes a copy to every subscriber in parallel, so it suits fanout to many endpoints. EventBridge routes to every target whose rule matches fields inside the event JSON, so it suits content-based routing and consuming AWS-service or SaaS event sources.
Trap Picking SNS to distribute a workload across a pool of competing workers so each item is handled once, when SNS copies every message to every subscriber; single-consumer-per-message work distribution is SQS.
- SQS is a poll-based queue where one consumer claims each message
An SQS queue durably holds messages until a consumer polls and explicitly deletes them, and competing consumers share the load, so it is the choice for distributing work, leveling spiky load, and buffering between tiers. Because each message is claimed by one consumer at a time, SQS is not a fanout mechanism. If several independent systems each need the same message, give each its own queue.
Trap Reaching for a single SQS queue to notify several independent systems: the message goes to just one consumer from the pool, not to all of them.
- SQS messages are retained 4 days by default, up to 14 days maximum
An unconsumed SQS message survives for the queue's retention period, which defaults to 4 days and can be raised to a 14-day maximum, after which SQS deletes it automatically. Retention governs how long an undelivered message waits for a consumer. It is unrelated to how long an in-flight message stays hidden while one consumer works on it.
Trap Raising the retention period to stop a message from reappearing mid-processing: retention controls how long an unconsumed message lives, not in-flight invisibility, which is the visibility timeout.
- Visibility timeout hides a received message so a second consumer doesn't grab it
When a consumer receives an SQS message it becomes invisible to other consumers for the visibility-timeout window, which defaults to 30 seconds and can be set up to 12 hours. If the consumer deletes the message before the window expires it is gone for good; if processing overruns the window the message reappears and may be processed again. So size the timeout to the real processing time, not the default.
Trap Leaving the visibility timeout at the 30-second default when processing routinely takes longer, so the message reappears and a second consumer reprocesses it before the first one finishes.
- Standard queues are at-least-once with best-effort ordering; FIFO queues add ordering and exactly-once processing
An SQS Standard queue gives at-least-once delivery (AWS states more than one copy of a message might be delivered) with only best-effort ordering, in exchange for nearly unlimited throughput. A FIFO queue preserves first-in-first-out order and provides exactly-once processing within its deduplication interval, at a lower throughput ceiling. Choose FIFO only when ordering or no-duplicates is a hard requirement, because it trades away throughput.
Trap Assuming a Standard queue preserves order because messages usually arrive in sequence: ordering is only best-effort, and duplicates can occur; strict order or no-duplicates needs FIFO.
- High-throughput FIFO mode raises a FIFO queue's per-queue throughput when you need more
A plain FIFO queue trades throughput for ordering and exactly-once processing. When you need higher throughput while keeping FIFO semantics, enable high-throughput FIFO mode, which raises the per-queue / per-API-action quota and scales with the number of distinct message group IDs: spreading messages across more message groups increases capacity. Without enough distinct group IDs the throughput gain doesn't materialize.
Trap Enabling high-throughput FIFO but routing every message through one message group ID, so the throughput stays bottlenecked because capacity scales with the number of distinct group IDs.
- A Lambda SQS event source mapping batches up to 10,000 messages for Standard but only 10 for FIFO
The Lambda SQS event source mapping reads messages in batches with a batch size that defaults to 10. Standard queues allow up to 10,000 messages per batch, but FIFO queues are capped at 10. Any batch size above 10 also requires a
MaximumBatchingWindowInSecondsof at least 1 second so Lambda waits long enough to fill the larger batch.Trap Setting a batch size above 10 for a FIFO source queue, which is capped at 10; the larger 10,000-message batches apply only to Standard queues.
- SNS is push-based pub/sub that delivers a copy to every subscriber: the fanout pattern
A publisher sends one message to an SNS topic and SNS pushes a copy to every subscriber in parallel, which is the fanout pattern for triggering several independent systems from one event. SNS does not store messages for later polling, so a subscriber that is offline at publish time loses that message. It is the right tool when one event must reach many endpoints at once.
Trap Assuming an offline SNS subscriber will pick up the message later: SNS is deliver-then-forget and keeps nothing for polling, so the message is lost unless a queue buffers it.
- Subscribe an SQS queue per consumer to SNS for durable, independent fanout
Because SNS itself keeps no copy, the resilient fanout pattern subscribes an SQS queue to the SNS topic for each downstream consumer. SNS pushes the message to every queue, and each consumer polls its own durable copy on its own schedule, so a consumer that is offline at publish time still processes the message when it returns. This combines SNS's one-to-many fanout with SQS's durability.
Trap Subscribing one shared SQS queue to the topic for several consumers, which makes them compete for each message so only one processes it; durable independent fanout needs one queue per consumer.
3 questions test this
- A company is building an event-driven architecture where a single event must be processed by multiple independent services. Each service…
- A developer is building an e-commerce platform where order events need to be processed by multiple independent services: inventory…
- A company is migrating a monolithic application to a microservices architecture. When an order is placed, multiple independent services…
- SNS subscription filter policies match on message attributes, not arbitrary body fields
An SNS subscription filter policy lets a subscriber receive only messages whose message attributes match the policy, so you can fan out selectively from one topic. The match is on attributes, not on arbitrary fields inside the message body. If routing must depend on content within the event JSON, that is EventBridge's job, not SNS's.
Trap Expecting an SNS filter policy to route on a field buried in the message body: SNS filters match message attributes only; content-based routing on the event JSON is EventBridge.
- EventBridge routes events to targets by rules that match fields inside the event JSON
EventBridge is a content-based event router: rules match on fields within the event's JSON body and deliver to the targets whose rule matches, rather than to a flat topic of subscribers. Reach for it when routing depends on event content, when consuming AWS-service or SaaS partner event sources, or when you need a schema registry. It delivers at-least-once to each target, just like SQS Standard and SNS.
Trap Choosing SNS subscription filter policies to route on fields inside the event payload, when those filters match only message attributes; matching on the event JSON body is EventBridge's content-based routing.
- An EventBridge archive retains events indefinitely by default and can replay them
EventBridge can archive matching events and later replay them onto a bus, useful for reprocessing or recovery. The archive's retention is configurable in days, but it defaults to indefinite retention, not a short window, so events are kept until you set a limit. SNS has no comparable replay; needing to replay past events is a strong cue for EventBridge.
Trap Assuming an EventBridge archive defaults to a short retention like 24 hours: the default is indefinite retention until you configure a day limit.
- At-least-once delivery makes idempotent consumers mandatory
SQS Standard delivery, SNS delivery to each subscriber, and EventBridge delivery to each target are all at-least-once, so a consumer can legitimately receive the same message more than once. A consumer is idempotent when processing the same message twice yields the same result as once. Without idempotency, duplicate deliveries produce duplicate side effects (double charges, double records), so design the consumer to tolerate repeats.
Trap Trusting that a Standard queue or SNS delivers each message exactly once so the consumer need not handle repeats, when these services are at-least-once and duplicates are expected, not exceptional.
- Implement idempotency with a DynamoDB conditional write on a dedup key
The canonical idempotency implementation derives a stable key from the message (its message ID or a business key) and writes it to DynamoDB with a conditional
attribute_not_existscheck. The first delivery's write succeeds; a duplicate delivery fails the condition, so the consumer skips the side effect instead of re-running it. If duplicates are simply unacceptable and ordering matters, an SQS FIFO queue removes the burden from your code instead.Trap Keying the dedup record on a value that changes between deliveries of the same logical message rather than a stable message ID or business key, so the conditional write never collides and duplicates slip through.
3 questions test this
- A financial services company uses AWS Lambda with an Amazon EventBridge rule to process stock trade events. Due to network issues, the same…
- A developer is building a product catalog application using the AWS SDK for Java and Amazon DynamoDB. The application must prevent…
- A developer is building an inventory management system using Amazon DynamoDB and the AWS SDK for Python (Boto3). The application must…
- Retry transient failures with exponential backoff plus jitter, not fixed-interval loops
When a dependency throttles or returns a 5xx, retrying immediately and in lockstep across many callers creates a synchronized retry storm that keeps the dependency overwhelmed. Exponential backoff roughly doubles the wait each attempt, and jitter adds a random offset so callers spread out instead of retrying in unison. Together they let a struggling dependency recover.
Trap Using a fixed-interval sleep-and-retry loop: without jitter every caller retries in unison, re-creating the retry storm the backoff was meant to avoid.
5 questions test this
- A development team is building an e-commerce application using the AWS SDK for Python (Boto3) to interact with Amazon DynamoDB. The…
- A developer is writing a Python Lambda function that uses the AWS SDK for Python (Boto3) to call an external API and then write data to…
- A developer is using the AWS SDK for Python (Boto3) to write 500 items to an Amazon DynamoDB table. The developer uses the BatchWriteItem…
- A developer is building a data migration application using the AWS SDK for Python (Boto3) to write thousands of items to an Amazon DynamoDB…
- A developer's application experiences intermittent ProvisionedThroughputExceededException errors when performing batch writes to an Amazon…
- The AWS SDK already retries throttling and transient errors, so tune its config instead of hand-rolling
The AWS SDKs implement automatic retries with exponential backoff and jitter for throttling and transient errors, so you adjust the SDK's retry configuration (retry mode and max attempts) rather than writing sleep loops by hand. Reserve custom retry-with-backoff, and a circuit breaker that stops calling a dependency that keeps failing, for third-party HTTP integrations the SDK does not own, so a failing downstream doesn't exhaust your function's concurrency.
Trap Hand-coding an exponential-backoff retry loop around AWS SDK calls to handle throttling, when the SDK already retries those errors and you only need to tune its retry mode and max attempts.
3 questions test this
- A developer creates an AWS Lambda function that invokes DynamoDB using the AWS SDK for JavaScript. During testing, the function…
- A developer is writing a Python Lambda function that uses the AWS SDK for Python (Boto3) to call an external API and then write data to…
- A developer is writing a Lambda function using the AWS SDK for Python (Boto3) to process messages from an Amazon SQS queue and store…
- Let the SDK pull temporary role credentials from the provider chain: never hardcode access keys
Application code reaches AWS through the language-specific AWS SDK (Boto3, AWS SDK for JavaScript v3, others) and the AWS CLI from the shell; both resolve credentials through the default credential provider chain. On Lambda or EC2 that means the attached IAM role's temporary credentials, and the SDK signs every request with them (SigV4) automatically. Grant the compute a role and let the SDK pull credentials from the chain rather than baking long-lived access keys into source or environment variables.
- Orchestration centralizes workflow control; choreography distributes it
In orchestration a single coordinator (an AWS Step Functions state machine) drives the steps, owns retries, and holds the workflow state in one place, which makes runs easy to visualize and debug. In choreography each service reacts to events via SNS or EventBridge with no central brain, which is looser and more scalable but hard to trace end-to-end. Choose orchestration when a multi-step workflow must be auditable and centrally coordinated.
Trap Using pure SNS/EventBridge choreography for a workflow that must be debugged end-to-end: with no central coordinator, tracing where a multi-step run failed is hard; Step Functions orchestration gives that visibility.
- Step Functions Standard workflows are exactly-once with built-in Retry/Catch; Express trades that for high volume
A Step Functions Standard workflow gives exactly-once execution, an auditable run history, and built-in Retry and Catch with backoff per state: the right fit for ordered, durable, traceable multi-step processes. Express workflows are tuned for high-volume, short-duration runs and do not provide the exactly-once durability of Standard. When a stem asks for an ordered, auditable workflow with visible state, that points to Standard.
Trap Choosing Express workflows for a long-running, auditable, exactly-once process because they cost less per run, when Express favors high-volume short bursts and gives up the exactly-once durability and full run history Standard provides.
- Long polling eliminates empty SQS ReceiveMessage responses and cuts cost
When an SQS consumer keeps getting empty ReceiveMessage responses on a sporadic queue and paying for those calls, enable long polling by setting ReceiveMessageWaitTimeSeconds to a value from 1 to 20 seconds (20 is the maximum). Long polling queries all SQS servers and waits until a message is available or the wait time expires, so it returns far fewer empty responses, lowers request cost, and still delivers messages promptly. Short polling (wait time 0) is the default and is what generates the costly empty replies.
Trap Switching to short polling, raising the visibility timeout, or adding more consumers to fix empty responses: the dial that removes empty responses is long polling via ReceiveMessageWaitTimeSeconds.
6 questions test this
- A developer is optimizing an Amazon SQS consumer application that processes messages from a queue with sporadic traffic patterns. Sometimes…
- A developer is building an application that polls an Amazon SQS queue for messages. The application runs on Amazon EC2 instances and…
- A developer is building a message processing application that polls messages from an Amazon SQS queue. During testing, the developer…
- A developer is optimizing an application that polls Amazon SQS for messages. The application currently makes frequent API calls that often…
- A developer is building a message processing application that polls an Amazon SQS queue. During testing, the application frequently returns…
- A developer is building a serverless application that polls an Amazon SQS queue for messages. The queue receives messages sporadically…
- Route poison SQS messages to a DLQ with a redrive policy and maxReceiveCount
To stop messages that repeatedly fail from blocking a queue, configure a redrive policy on the source queue that names the dead-letter queue in deadLetterTargetArn and sets maxReceiveCount to the number of receives allowed before SQS moves the message to the DLQ (for example 5). The DLQ must be the same type as the source: a FIFO source needs a FIFO DLQ. The redrive policy lives on the source queue, not the DLQ.
Trap Setting the redrive policy on the dead-letter queue itself: the policy and maxReceiveCount belong on the SOURCE queue, which points at the DLQ.
7 questions test this
- A developer is building a microservices application where an order processing service publishes messages to an Amazon SQS queue. The…
- A developer is implementing error handling for an Amazon SQS-based order processing system. Orders that cannot be processed after multiple…
- A developer is building an order processing application that uses Amazon SQS. The application occasionally fails to process certain…
- A developer is building an order processing application that uses Amazon SQS. Messages occasionally fail to process due to temporary…
- A developer is building an order processing application where messages are sent to an Amazon SQS queue. The application occasionally fails…
- A developer is building a distributed order processing system where messages in an Amazon SQS queue occasionally fail to process due to…
- A developer is building a distributed order processing system using Amazon SQS. Messages occasionally fail to process due to transient…
- ReportBatchItemFailures retries only the failed records in a batch
By default, when one record in a Lambda batch from SQS, Kinesis, or DynamoDB Streams fails, the whole batch is retried and already-succeeded records are reprocessed. To retry only the failures, set the event source mapping's FunctionResponseTypes to ReportBatchItemFailures and return a batchItemFailures list containing the identifiers (messageId for SQS, sequence number for Kinesis/DynamoDB Streams) of just the failed records. Lambda then makes only those records visible again.
Trap Expecting partial-batch behavior automatically: without ReportBatchItemFailures enabled AND a batchItemFailures response, a single failure re-drives the entire batch.
5 questions test this
- A developer is configuring an event source mapping between an Amazon SQS standard queue and a Lambda function. The Lambda function has a…
- A developer is building a data pipeline where an AWS Lambda function processes records from an Amazon Kinesis data stream. The function…
- A development team deploys an AWS Lambda function that processes messages from an Amazon SQS queue. The function occasionally fails to…
- A developer is processing records from an Amazon DynamoDB stream using AWS Lambda with an event source mapping. The function processes…
- A developer has a Lambda function that processes messages from an Amazon SQS queue using an event source mapping. When processing a batch…
- Lambda proxy integration passes the whole request in the event object
With Lambda proxy integration (AWS_PROXY), API Gateway maps the entire client request into the Lambda event object: event.httpMethod, event.path, event.pathParameters, event.queryStringParameters, event.headers, and the raw event.body (a string the function must parse, e.g. json.loads). Caller metadata such as the source IP and stage name live under event.requestContext (requestContext.identity.sourceIp, requestContext.stage). The function reads request data from this event rather than from any framework-style request object.
Trap Multi-value headers and query strings are NOT in headers/queryStringParameters: they are exposed separately as multiValueHeaders and multiValueQueryStringParameters.
10 questions test this
- A developer is creating a REST API using Amazon API Gateway with Lambda proxy integration. The API exposes a single resource /orders with…
- A developer is implementing an AWS Lambda function that will be invoked through Amazon API Gateway using Lambda proxy integration. The…
- A developer is troubleshooting an Amazon API Gateway REST API with Lambda proxy integration. The Lambda function needs to read query string…
- A development team is building a serverless application with Amazon API Gateway and AWS Lambda. The team needs to minimize API…
- A developer is configuring an Amazon API Gateway REST API with a Lambda proxy integration. The developer needs the Lambda function to…
- A developer is building a REST API using Amazon API Gateway with Lambda proxy integration. The Lambda function needs to access the HTTP…
- A developer is building a REST API using Amazon API Gateway with Lambda proxy integration. The Lambda function needs to access query string…
- A developer is building a REST API using Amazon API Gateway with AWS Lambda integration. The Lambda function must receive query string…
- A developer is building an API using Amazon API Gateway REST API with Lambda proxy integration. The API uses a greedy path variable…
- A company uses Amazon API Gateway with Lambda proxy integration to expose a REST API. The Lambda function needs to access the HTTP method,…
- A proxy-integration Lambda must return statusCode, headers, and a string body or API Gateway answers 502
With Lambda proxy integration the function itself shapes the HTTP response, which must be a JSON object with an integer statusCode, a headers map, and a body that is a STRING (serialize objects yourself). If the function returns a malformed shape (a bare object, a non-string body, or missing statusCode), API Gateway cannot translate it and returns 502 Bad Gateway with 'Internal server error', even though the function ran successfully.
Trap Seeing a 502 with successful function logs and blaming the function code: the cause is almost always a response not in the {statusCode, headers, body-as-string} shape.
2 questions test this
- With proxy integration, CORS headers must come from the Lambda response
Under Lambda proxy integration, API Gateway passes responses straight through, so the actual cross-origin headers (Access-Control-Allow-Origin, and as needed Access-Control-Allow-Methods/Headers) must be added by the Lambda function in its response object. The console's 'Enable CORS' only wires up the OPTIONS preflight (a MOCK integration) and cannot inject headers into your GET/POST responses. Configure both: an OPTIONS method for preflight plus the headers returned by the function.
Trap Assuming the console 'Enable CORS' button alone fixes proxy-integration CORS: it handles only preflight; the per-method response headers still have to be returned by the Lambda function.
8 questions test this
- A developer is configuring an Amazon API Gateway REST API with Lambda proxy integration. The developer needs to return custom CORS headers…
- A development team is building a RESTful API using Amazon API Gateway with AWS Lambda as the backend. The API must allow cross-origin…
- A developer is configuring a REST API in Amazon API Gateway with Lambda proxy integration. The API must support CORS to allow browser-based…
- A development team is building a serverless web application using Amazon API Gateway REST API with Lambda proxy integration. The frontend…
- A developer is building a single-page web application that calls an Amazon API Gateway REST API with Lambda proxy integration from a…
- A company has a REST API deployed on Amazon API Gateway with Lambda proxy integration. When browsers make requests to the API from a web…
- A development team builds a single-page web application hosted on Amazon S3 that calls an Amazon API Gateway REST API with Lambda proxy…
- A developer needs to enable CORS support for a REST API built with Amazon API Gateway using Lambda proxy integration. The API receives…
- API Gateway request validation rejects bad payloads before the backend runs
To validate that requests carry required fields and conform to types/ranges without writing validation in Lambda, define a JSON Schema model in API Gateway and attach a request validator (with ValidateRequestBody enabled) to the method. API Gateway checks the body against the model and returns 400 Bad Request itself for invalid requests, so the backend Lambda is never invoked, saving cost and centralizing validation.
Trap Validating required fields inside the Lambda function when the goal is to block invalid requests early: a model plus request validator rejects them at API Gateway before invocation.
4 questions test this
- A developer is building an API using Amazon API Gateway with Lambda integration. The API should validate that incoming POST requests…
- A company has an Amazon API Gateway REST API with Lambda integration. The API must validate incoming POST requests before invoking the…
- A developer is configuring an Amazon API Gateway REST API with request validation. The API accepts POST requests with a JSON body that must…
- A developer is building a REST API using Amazon API Gateway that accepts order data from clients. The API must validate that incoming…
- Use non-proxy (custom AWS) integration with VTL mapping templates to transform requests/responses
When the API must reshape the payload (transform the incoming request before Lambda, convert the Lambda response before the client, or override the status code) use Lambda custom (non-proxy, AWS-type) integration and write Velocity Template Language (VTL) mapping templates in the integration request and integration response. Lambda proxy integration passes data through unchanged and offers no mapping templates, so it cannot do this transformation.
Trap Choosing proxy integration when payload transformation/mapping templates are required: proxy is pass-through; mapping templates exist only on non-proxy (AWS) integrations.
6 questions test this
- A developer is creating a REST API using Amazon API Gateway and AWS Lambda. The API needs to transform incoming JSON request data before…
- A company is modernizing its API architecture. The development team is choosing between Lambda proxy integration (AWS_PROXY) and Lambda…
- A company has a REST API deployed on Amazon API Gateway that integrates with an AWS Lambda function using Lambda non-proxy integration. The…
- A developer is building an API Gateway REST API with Lambda non-proxy integration. The backend Lambda function returns data in a different…
- A developer is implementing an API using Amazon API Gateway and needs to choose between Lambda proxy integration and Lambda custom…
- A developer is building an Amazon API Gateway REST API that integrates with AWS Lambda. The API must transform incoming request data before…
- Lambda authorizers do custom auth and return an IAM policy; TOKEN vs REQUEST differ by identity source
For authorization logic API Gateway can't do natively (validating a JWT, checking custom claims, or querying a database) use a Lambda authorizer, which returns an IAM policy (Allow/Deny) plus an optional context object passed to the backend. A TOKEN authorizer takes a single bearer token from one header and can pre-screen it with a regex before invoking; a REQUEST authorizer can use multiple identity sources (headers, query strings, stage variables) as both input and the authorization cache key.
Trap Reaching for a Cognito authorizer when business rules require a database lookup or multi-source input: that custom logic needs a Lambda authorizer (REQUEST type for multiple identity sources).
4 questions test this
- A company is implementing authorization for its REST API in Amazon API Gateway. The API must authenticate users using JWT tokens from the…
- A developer is implementing a REST API using Amazon API Gateway with AWS Lambda integration. The API requires authorization based on…
- A developer is implementing authentication for a REST API on Amazon API Gateway. The API must validate JSON Web Tokens (JWTs) provided in…
- A company is building a serverless API using Amazon API Gateway with Lambda integration. The API must authenticate requests using JSON Web…
AWS Lambda Functions
Read full chapterCheat sheet
Sharp facts the exam loves — scan these before test day.
- Tune Lambda with memory: CPU scales with it
Memory is the only direct sizing dial on a Lambda function, settable from 128 MB to 10,240 MB, and vCPU is allocated proportionally rather than configured separately. A function reaches roughly one full vCPU at 1,769 MB and up to six vCPUs at the maximum, so a CPU-bound function can finish faster at higher memory and sometimes cost less overall even though the per-millisecond rate rises. Treat memory as the performance tuning knob, not just a capacity ceiling.
Trap Assuming raising memory always costs more: for a CPU-bound function the shorter duration can offset or beat the higher per-ms rate.
- A Lambda invocation is capped at 15 minutes
A single Lambda execution can run at most 15 minutes (900 seconds), the maximum configurable timeout. Work that needs longer must be split into smaller invocations or moved to a service built for long-running compute such as ECS, Fargate, or Step Functions for orchestration.
- Init code runs once per environment, not once per request
Lambda runs everything outside the handler (SDK clients, database connection pools, configuration loads) once during the init phase of a new execution environment, then reuses that warm environment across later invocations where only the handler body runs. This is why you place expensive setup at module scope: it is amortized across many requests instead of repeated per call.
Trap Putting SDK client and connection-pool setup inside the handler, where it re-runs on every invocation and throws away the warm-environment reuse that makes module-scope init cheap.
6 questions test this
- A developer is building an AWS Lambda function in Python that uses the AWS SDK for Python (Boto3) to write data to Amazon DynamoDB. The…
- A developer has deployed an AWS Lambda function that processes messages from an Amazon SQS queue. The function uses the AWS SDK for…
- A developer is optimizing a Python Lambda function that retrieves configuration from AWS Systems Manager Parameter Store. The function is…
- A developer is building a Python Lambda function that uses the AWS SDK (Boto3) to interact with Amazon DynamoDB. The function experiences…
- A developer is building an AWS Lambda function in Python that uses the AWS SDK (Boto3) to query Amazon DynamoDB. During testing, the…
- A developer is optimizing an AWS Lambda function that retrieves configuration data from AWS Systems Manager Parameter Store. The function…
- /tmp is ephemeral scratch space, never durable state
Each execution environment gets an ephemeral
/tmpdirectory, configurable from 512 MB up to 10,240 MB (10 GB), that lives only for the life of that environment and can vanish at any time. Use it for scratch work within an invocation, but never as a database or for state that must survive: persist anything durable to S3, DynamoDB, or EFS instead.Trap Caching data in
/tmpand expecting later invocations to read it: a fresh environment starts with an empty/tmpand the data is gone.- Layers share libraries without rebundling: up to five per function
A Lambda layer packages shared libraries, a custom runtime, or dependencies separately so multiple functions reuse them instead of bundling the same code into every deployment package. You can attach up to five layers to a function, and their unzipped contents count against the same 250 MB unzipped limit as the function code.
Trap Treating layers as a way around the 250 MB unzipped limit, when layer contents count against that same ceiling and so don't expand your total package budget.
3 questions test this
- A developer is building a serverless application with multiple Lambda functions. Several functions require the same set of dependencies…
- A developer is designing a serverless application that will consist of 25 Lambda functions. Each function requires five third-party…
- A developer is designing a serverless application with 15 Lambda functions. Several functions require the same set of libraries, but the…
- Zip caps at 50 MB direct / 250 MB unzipped; containers go to 10 GB
A .zip deployment package is limited to 50 MB when uploaded directly and 250 MB unzipped including all attached layers, and uploading the zip from S3 raises only the direct-upload limit, not the 250 MB unzipped ceiling. A container image pushed to Amazon ECR raises the ceiling all the way to 10 GB, so large dependency trees, ML models, or custom runtimes point to a container image rather than a zip.
Trap Reaching for an S3-hosted zip to fit a 400 MB dependency tree: S3 lifts the upload size but the 250 MB unzipped limit still applies, so the answer is a container image.
5 questions test this
- A developer is building a serverless application with multiple Lambda functions. Several functions require the same set of dependencies…
- A developer is designing a serverless application that will consist of 25 Lambda functions. Each function requires five third-party…
- A developer is designing a serverless application with 15 Lambda functions. Several functions require the same set of libraries, but the…
- A developer is designing a serverless application with 12 Lambda functions that share three different sets of dependencies: a data access…
- A developer is building a Lambda function that requires the requests and pandas libraries. The function code is 5 MB, the requests library…
- Execution role = what the function may do (outbound)
The execution role is the IAM role a Lambda function assumes at runtime to call other AWS services, such as reading a DynamoDB table or writing to S3: it is the function's outbound permission set. Without the right action in this role, the function's own SDK calls to other services fail with access-denied, regardless of who is allowed to invoke the function.
Trap Fixing the function's own access-denied SDK calls by editing who can invoke it, when outbound calls fail because the execution role lacks the action, not because of an invoke permission.
15 questions test this
- A developer creates an AWS Lambda function using the AWS SDK for Python (Boto3) to process orders and write data to Amazon DynamoDB. The…
- A developer is configuring an AWS Lambda function to access configuration parameters stored in AWS Systems Manager Parameter Store. The…
- A developer is troubleshooting a Lambda function that executes successfully but is not generating any logs in Amazon CloudWatch Logs. The…
- A developer builds a document processing application where users upload PDF files to an S3 bucket. A Lambda function is triggered by the S3…
- A developer is creating an AWS Lambda function that needs to retrieve database credentials stored as a SecureString parameter in AWS…
- A developer is troubleshooting an AWS Lambda function that is triggered by Amazon S3 object creation events. The S3 event notification is…
- A developer creates an AWS Lambda function that processes image files uploaded to an Amazon S3 bucket. The function needs to read objects…
- A developer is building an image processing application that uses an AWS Lambda function to generate thumbnails when images are uploaded to…
- A developer is creating an AWS Lambda function that processes images uploaded to an Amazon S3 bucket. The Lambda function needs to read the…
- A developer is building an image processing application. When an image file is uploaded to an Amazon S3 bucket, an AWS Lambda function must…
- A developer deploys a Python Lambda function that uses the print() function to output log messages. After invoking the function, the…
- A developer creates an AWS Lambda function to process images uploaded to an Amazon S3 bucket. The function code uses the AWS SDK to read…
- A developer deploys an AWS Lambda function that processes data and uses print statements to log messages. After invoking the function…
- A developer is creating an AWS Lambda function that uses the AWS SDK for Python (Boto3) to write data to an Amazon DynamoDB table. During…
- A developer is building a Lambda function triggered by Amazon S3 PUT events. The function uses the AWS SDK to download the uploaded object…
- Resource-based policy = who may invoke the function (inbound)
A Lambda function's resource-based policy controls inbound access: which accounts or services (API Gateway, Amazon S3, EventBridge, SNS) are permitted to invoke it. When you wire up an S3 event or an API Gateway integration, that grant is added here: it governs the opposite direction from the execution role, so anchor the two by direction of access.
Trap Adding the invoke permission to the execution role: inbound invoke rights belong on the function's resource-based policy, not the role the function assumes.
6 questions test this
- A developer is creating an AWS Lambda function to process images uploaded to an Amazon S3 bucket. The developer uses the AWS CLI to…
- A developer creates an AWS Lambda function that processes image files uploaded to an Amazon S3 bucket. The function needs to read objects…
- A developer is creating an AWS Lambda function that processes images uploaded to an Amazon S3 bucket. The Lambda function needs to read the…
- A developer creates an Amazon EventBridge rule that triggers an AWS Lambda function whenever an Amazon EC2 instance changes state to…
- A developer is using Amazon API Gateway stage variables to dynamically configure which Lambda function alias to invoke based on the…
- A developer is troubleshooting an Amazon API Gateway REST API that uses Lambda proxy integration. The API consistently returns 500 Internal…
- Poll-based sources need permissions in the execution role, not a resource policy
For poll-based sources like SQS, Kinesis Data Streams, and DynamoDB Streams there is no resource-based policy granting them inbound access, because Lambda itself reads from the source on your behalf. The execution role must therefore carry the polling permissions (such as
sqs:ReceiveMessageor the stream read/describe actions). Push sources need the resource policy; poll sources need the execution role.Trap Adding a resource-based policy to let SQS or Kinesis invoke the function, when poll sources are read by Lambda using the execution role's permissions, so the resource policy does nothing here.
- Synchronous invocation: the caller owns retries
A synchronous (
RequestResponse) invocation (API Gateway, the CLIinvokedefault) runs the function and returns the result to a caller that waits. Lambda performs no retry on its own, so if the function errors the caller decides what happens next; a 500 from API Gateway means the client (or the integration) must handle the retry and error path.Trap Expecting Lambda to retry a failed synchronous invocation, when on the RequestResponse path Lambda retries nothing and the waiting caller owns the retry and error handling.
- Asynchronous invocation: Lambda owns retries, default 2
An asynchronous (
Event) invocation (S3 events, EventBridge, SNS) hands the event to an internal Lambda-managed queue and immediately returns a 202, so the caller does not wait. Because the caller is already gone, Lambda owns the retries and re-attempts a failed invocation twice by default (three attempts total) with delays before the event is dropped unless you capture it.Trap Reading the immediate 202 from an async invocation as the function having succeeded, when it only means the event was accepted onto Lambda's queue and the function may still fail and be retried.
5 questions test this
- A developer is building an order processing application using AWS Lambda functions triggered asynchronously by Amazon S3 events. The Lambda…
- A developer is building an AWS Lambda function using Python that is invoked asynchronously by Amazon SNS. The function occasionally fails…
- A developer is configuring error handling for an AWS Lambda function that processes payment transactions asynchronously. The function must…
- A developer is configuring error handling for an AWS Lambda function that is invoked asynchronously by Amazon SNS. The function…
- A developer creates a Lambda function that is invoked asynchronously by Amazon S3 when objects are uploaded. The function occasionally…
- Capture both outcomes with destinations; a DLQ catches only failures
For asynchronous invocations, a dead-letter queue (an SQS queue or SNS topic) receives only the failed event payload, whereas Lambda destinations route both success and failure outcomes (with richer context including the request, response, and error) to SQS, SNS, EventBridge, or another function. Destinations are the modern, preferred mechanism, so when a question asks how to capture both success and failure of an async invocation, the answer is destinations.
Trap Choosing a dead-letter queue to capture successful async outcomes: a DLQ only ever receives failed events; success capture requires destinations.
13 questions test this
- A developer is building an event-driven application where an AWS Lambda function is invoked asynchronously by Amazon S3 when objects are…
- A developer is building a serverless application where Lambda functions are invoked asynchronously by Amazon S3 events. The developer needs…
- A developer is building an order processing application using AWS Lambda with asynchronous invocations from Amazon S3. When orders fail…
- A developer is building an order processing application using AWS Lambda functions triggered asynchronously by Amazon S3 events. The Lambda…
- A developer configures a Lambda function for asynchronous invocation to process image uploads. When the function fails after exhausting all…
- A company is building an event-driven application that processes customer orders. When a Lambda function fails to process an order event…
- A developer is building an AWS Lambda function using Python that is invoked asynchronously by Amazon SNS. The function occasionally fails…
- A developer is configuring error handling for an AWS Lambda function that processes payment transactions asynchronously. The function must…
- A developer has an AWS Lambda function that processes messages from an Amazon SNS topic asynchronously. When the function encounters an…
- A developer has configured an AWS Lambda function to be invoked asynchronously by Amazon S3 events. The function occasionally fails due to…
- A developer is building an event-driven application where Amazon S3 triggers an AWS Lambda function asynchronously when files are uploaded.…
- A developer creates a Lambda function that is invoked asynchronously by Amazon S3 when objects are uploaded. The function occasionally…
- A developer has configured an AWS Lambda function that is triggered asynchronously by Amazon S3 when objects are uploaded. The function…
- Event source mappings poll the source and own the batch/retry settings
An event source mapping is a Lambda-managed poller for stream and queue sources (SQS, Kinesis Data Streams, DynamoDB Streams, Amazon MSK) that reads records, groups them into a batch, and invokes the function with that batch. The mapping (not the function) owns the tuning and retry behavior, which is the key distinction from async invocation where retry settings live on the function.
Trap Tuning batch and retry behavior for an SQS or Kinesis source on the function's async settings, when for poll-based sources those settings live on the event source mapping instead.
- Batch size and batch window trade latency for fewer invocations
An event source mapping's batch size sets the maximum records per invocation, while the batch window (
MaximumBatchingWindowInSeconds, up to 300 seconds) lets the poller wait to accumulate a fuller batch before invoking. Raising either reduces the number of invocations at the cost of added latency, so tune them together to balance throughput against how quickly records must be processed.Trap Raising the batch window to cut invocation count without expecting added latency, when the poller waits to fill the batch, so records sit longer before processing.
- Set an SQS visibility timeout of at least 6× the function timeout
When SQS is the event source, set the source queue's visibility timeout to at least six times the function's timeout. The longer window keeps an in-flight batch hidden from other consumers while the function processes it, so a slow batch is not redelivered and processed twice before the original invocation finishes.
Trap Leaving the SQS visibility timeout at the 30-second default for a multi-minute function: the message reappears mid-processing and gets handled again.
- Account concurrency defaults to 1,000 with a 100-execution shared floor
Concurrency is the number of requests in flight simultaneously across a function, and every function in a Region shares a default account ceiling of 1,000 concurrent executions (raisable via a quota request). Lambda always keeps at least 100 of that pool unreserved as a shared floor, so reserving capacity for one function can never starve all the others below that minimum.
Trap Reserving concurrency until the pool's unreserved remainder hits zero, when Lambda blocks reservations that would drop the shared unreserved floor below 100.
- Reserved concurrency is a free cap-and-guarantee, not a warm pool
Reserved concurrency carves out a guaranteed slice of the account pool for one function and simultaneously caps that function at that number. It protects a downstream resource (say a database with a fixed connection limit) from being overwhelmed and guarantees the function some capacity against noisy neighbors. It adds no extra charge and pre-warms nothing, so a reserved environment still cold-starts.
Trap Reaching for reserved concurrency to eliminate cold starts: it caps and guarantees capacity but pre-warms nothing; the latency fix is provisioned concurrency.
- Cut cold starts with provisioned concurrency, slimmer packages, and lighter init
A cold start is the latency added when a request lands with no warm environment and Lambda must download code, start the runtime, and run init before the handler. Reduce it by using provisioned concurrency for a deterministic fix, shipping slimmer packages with fewer dependencies for faster download and init, and moving heavy one-time setup outside the handler so it is reused across invocations.
Trap Adding RAM to a function purely to shrink cold starts, when more memory speeds the handler's CPU-bound work but doesn't remove the init phase, whereas provisioned concurrency does.
- A published version is an immutable snapshot; $LATEST is mutable
Publishing a version freezes the function's code and configuration as an immutable, numbered snapshot, while
$LATESTis the mutable working copy you keep editing. You publish a version to pin a known-good build that later releases and aliases can point at, since the numbered version can never change after publication.Trap Expecting to patch the code of a published numbered version in place, when versions are immutable, so a fix means publishing a new version and re-pointing the alias.
- Shift traffic safely with an alias and weighted routing
An alias is a named, movable pointer (for example
prod) to a version, so callers target the alias and you re-point it to ship a release. An alias also supports weighted routing, splitting traffic between two versions (say 90% to v1 and 10% to v2) to run a canary or blue/green rollout and shift weight as confidence grows.Trap Pointing an alias's weighted routing at $LATEST for a canary, when weighted aliases split traffic between two published numbered versions, not the mutable $LATEST.
- Provisioned concurrency attaches to a version or alias, not $LATEST
Provisioned concurrency is configured on a specific version or alias, not on
$LATEST. A deployment that re-points an alias to a fresh, un-provisioned version reintroduces cold starts until provisioning catches up on the new target, so plan provisioning around the release rather than assuming it follows the alias automatically.Trap Expecting provisioned concurrency to follow an alias to a new version: the new version starts un-provisioned and cold-starts until you provision it.
- VPC attachment reaches private resources but loses default internet egress
By default a Lambda function runs in a Lambda-managed network with internet access. Attaching it to a VPC by specifying subnets and security groups lets it reach private resources like an RDS instance, but it then loses default internet egress, so reaching the public internet or AWS service endpoints now requires a NAT gateway or VPC interface endpoints.
Trap Assuming a VPC-attached function keeps internet access: it does not; outbound to the internet or public AWS endpoints needs a NAT gateway or VPC endpoints.
- Layer contents must use the runtime's directory convention under /opt
Lambda extracts every attached layer into /opt and adds language-specific subpaths to the search path, so a layer's zip must place dependencies in the directory the runtime expects: python/ (or python/lib/python3.x/site-packages/) for Python, nodejs/node_modules/ for Node.js. Dependencies zipped at the archive root are not found and imports fail with ModuleNotFound. The same rule lets container-image functions reuse a layer by copying its contents into /opt during the Docker build, since layers cannot be attached to container-based functions.
Trap Zipping libraries at the root of the layer archive: they must sit under python/ or nodejs/node_modules/ for the runtime to import them.
9 questions test this
- A developer is working on a Node.js Lambda function and wants to use a specific version of the AWS SDK that differs from the version…
- A developer is creating an AWS Lambda layer to share a common Python library called 'analytics-utils' across multiple Lambda functions in…
- A company deploys Lambda functions using container images stored in Amazon ECR. The development team wants to use a common set of libraries…
- A developer is creating a Node.js Lambda function that requires the lodash library. The developer packages the library in a Lambda layer…
- A development team is building a Python application that uses multiple Lambda functions. The functions share common utility code and…
- A development team is building multiple Python Lambda functions that share common utility libraries. The team creates a Lambda layer to…
- A company packages its Lambda functions as container images stored in Amazon ECR. A developer wants to use an existing Lambda layer that…
- A development team needs to share a common set of Python libraries across 15 Lambda functions. The team creates a Lambda layer with the…
- A development team at a logistics company creates multiple Python Lambda functions that use common database utility libraries. The team…
- Layer binaries must match the function's runtime version and the Linux/arm architecture
A layer's native code is tied to the runtime and platform it was built for: packages compiled against Python 3.12 fail on a 3.9 function, and libraries built on Windows or for the wrong CPU architecture fail in Lambda's Linux environment. Build layer dependencies (especially compiled ones like pandas/numpy) on Linux for the target runtime version and architecture (x86_64 or arm64). Interpreted languages like Go that compile to a single self-contained binary don't benefit from layers: bundle dependencies into the deployment package instead.
Trap Packaging a Lambda layer with pip on a Windows laptop and attaching it directly: Windows-compiled native modules are incompatible with Lambda's Linux runtime.
3 questions test this
- A company is modernizing a monolithic application by migrating shared utility code to Lambda layers. The team packages the utilities and…
- A company is building Lambda functions using Go for a high-performance data processing pipeline. The team wants to use Lambda layers to…
- A developer is creating a Lambda layer containing Python dependencies including pandas and numpy for use by multiple Lambda functions. The…
Grant other accounts use of a layer version with lambda add-layer-version-permission, which sets a resource policy granting lambda:GetLayerVersion. Permissions are per layer VERSION, so each new version must be re-shared. Name a specific account ID as the principal for one account; to share with a whole AWS Organization, set the principal to '*' and pass the organization-id parameter so only accounts in that org can use it.
Trap Assuming sharing a layer covers future versions: each published version is a separate resource, so consumers can't see version N+1 until you run add-layer-version-permission for it.
7 questions test this
- A company has multiple development teams that each maintain their own AWS accounts. The platform team wants to share a Lambda layer…
- A company has a central platform team that maintains a Lambda layer containing standardized logging and monitoring utilities. The platform…
- A company has a central platform team that maintains shared Lambda layers containing common logging and tracing libraries. Multiple…
- A company has a central platform team that manages shared libraries across multiple AWS accounts within an AWS Organization. The team needs…
- A developer maintains Lambda layers in a central AWS account that are shared with multiple application development accounts in the…
- A development team in AWS Account A has created a Lambda layer containing shared utility functions. The team needs to allow Lambda…
- A company has multiple development teams building Lambda functions that require a common set of utility libraries. A platform team creates…
- The Parameters and Secrets Lambda Extension caches values; SSM_PARAMETER_STORE_TTL controls staleness
The AWS Parameters and Secrets Lambda Extension fetches Parameter Store and Secrets Manager values over a local HTTP endpoint and caches them in the execution environment, cutting API calls, latency, and throttling for frequently invoked functions. The cache lifetime is the SSM_PARAMETER_STORE_TTL environment variable: a longer TTL means fewer API calls but a value can stay stale for that window after a change, so lower the TTL when freshness matters. Requests to the extension endpoint must include the X-Aws-Parameters-Secrets-Token header set to AWS_SESSION_TOKEN.
Trap Blaming Parameter Store when a Lambda keeps returning an old value after an update: it is the extension's cache; shorten SSM_PARAMETER_STORE_TTL.
4 questions test this
- A developer is using the AWS Parameters and Secrets Lambda Extension to retrieve configuration values from AWS Systems Manager Parameter…
- A developer is building an AWS Lambda function that needs to access an API key stored in AWS Systems Manager Parameter Store. The developer…
- A company uses the AWS Parameters and Secrets Lambda Extension to retrieve Parameter Store values in their Lambda functions. The company…
- A company has multiple AWS Lambda functions that retrieve configuration data from AWS Systems Manager Parameter Store. The functions…
- Fetch a whole Parameter Store hierarchy in one call with GetParametersByPath
When configuration is organized as a path hierarchy (e.g. /myapp/prod/database/...), retrieve all of it in a single GetParametersByPath call instead of one GetParameter per key; set Recursive=true to include nested levels. Storing the environment name in an env var and building the path lets the same function load per-environment config. The execution role needs ssm:GetParametersByPath permission for that path.
Trap Calling GetParameter (or GetParameters) per key for a whole tree: GetParametersByPath with Recursive=true returns the entire branch in one request.
4 questions test this
- A developer is designing a Lambda function configuration strategy for a multi-environment deployment (development, staging, production).…
- A development team is deploying an AWS Lambda function across multiple environments (development, staging, production). Each environment…
- A developer is configuring an AWS Lambda function to access configuration parameters stored in AWS Systems Manager Parameter Store. The…
- A developer is building multiple AWS Lambda functions that share common configuration stored in AWS Systems Manager Parameter Store. The…
- Emit structured JSON logs so CloudWatch Logs Insights can query them by field
To make Lambda logs searchable by custom fields (correlationId, errorType, status code) and Lambda context (request ID, function name), output structured JSON, either via the Lambda advanced logging controls (set log format to JSON and an application log level) or the Powertools for AWS Lambda Logger, whose inject_lambda_context decorator auto-adds request context. Then query with CloudWatch Logs Insights using fields/filter/stats, e.g. filter on a field and stats count(*) by bin(1h) to trend errors over time.
Trap Logging free-text strings and trying to parse them later: Logs Insights filters and aggregates by field only when entries are structured JSON.
6 questions test this
- A developer is implementing structured logging in a Python Lambda function to improve debugging capabilities. The developer wants to…
- A developer is troubleshooting a production Lambda function that intermittently returns errors. The function processes customer data and…
- A developer is building a Lambda function that calls a third-party REST API. The function must implement proper error handling and log all…
- A company runs an AWS Lambda function that processes customer orders from Amazon API Gateway. The development team wants to configure the…
- A developer is building an AWS Lambda function using Python that processes customer orders. The function occasionally fails when calling a…
- A developer is troubleshooting a production Lambda function that intermittently returns errors. The function uses JSON structured logging.…
Application Data Stores
Read full chapterUnlock with Premium — includes all practice exams and the complete study guide.
Security
Authentication and Authorization
Read full chapterCheat sheet
Sharp facts the exam loves — scan these before test day.
- Authentication proves who you are; authorization decides what you may do
Authentication and authorization are two separate steps, and an exam scenario almost always turns on telling them apart. Authentication verifies an identity (a SigV4-signed AWS request, a JWT validated by Cognito, or a federated login) while authorization is a distinct policy decision about what that verified identity may do, so a perfectly authenticated caller can still be denied. The practical consequence: a credential that proves identity (a Cognito ID token) is not the credential that grants access (an OAuth 2.0 access token or temporary AWS credentials).
Trap Treating a successful sign-in as proof a call is allowed: authorization is evaluated separately, so an authenticated principal can still hit an explicit deny.
- An explicit Deny always beats any Allow
AWS authorization is allow + no-explicit-deny: a request is permitted only when some policy allows the action on the resource AND no policy anywhere contains an explicit
Deny. A single explicitDenyoverrides everyAllow, which is why even an admin principal can be blocked from an S3 bucket whose bucket policy denies its ARN. Anything not explicitly allowed is denied by default (implicit deny), but that default is weaker than an explicit deny. Only an explicitAllowcan overcome an implicit deny, and nothing overcomes an explicit one.Trap Assuming an Allow on an admin or broadly-permissive policy can override an explicit Deny elsewhere, when a single explicit Deny wins over every Allow in the evaluation.
6 questions test this
- A developer is troubleshooting an access denied error when an AWS Lambda function attempts to retrieve a secret from AWS Secrets Manager.…
- A company is implementing a permissions boundary to limit what IAM roles developers can create for their Lambda functions. The security…
- A developer is configuring a Lambda function that uses environment variables to store an API key. The company requires that only specific…
- A company's security policy requires that all IAM roles created for Lambda functions can only access specific secrets in AWS Secrets…
- A developer is troubleshooting an IAM policy issue. A user has an identity-based policy that allows ec2:TerminateInstances on all EC2…
- A developer is troubleshooting an access denied error for an AWS Lambda function that needs to read from an S3 bucket. The Lambda…
- Same account: an Allow in either the identity or the resource policy is enough
For a request within one account, AWS takes the union of the identity-based policy (attached to the user/role) and the resource-based policy (attached to the S3 bucket, Lambda function, SQS queue, etc.): an
Allowin either one (or both) grants the action. Identity-based policies attached to a principal are themselves additive, so multiple attached policies combine. The notable exception is KMS, where the key policy must allow the principal explicitly for IAM permissions to take effect.Trap Assuming KMS follows the union rule: a KMS key policy must grant the principal explicitly, so an identity policy alone is not sufficient.
- Cross-account access needs an Allow in BOTH accounts
When the principal and the resource live in different accounts, the union rule no longer applies: you need an
Allowin the caller's identity-based policy in its own account AND anAllowin the resource-based policy (or role trust policy) in the resource's account. Both sides must opt in, either one alone fails. This is the single behavioral difference between same-account and cross-account evaluation.Trap Granting only the resource-based policy in the target account and expecting cross-account access to work: the caller's own account must also allow the action on its identity.
10 questions test this
- A developer is creating an application that runs in AWS account A and needs to access an Amazon S3 bucket in AWS account B. The developer…
- A company maintains database credentials in AWS Secrets Manager in a centralized security account (Account A). Application workloads…
- A developer is configuring cross-account access between a production account and a development account. The development account (Account A)…
- A company stores data in an Amazon S3 bucket with SSE-KMS default encryption using a customer managed key. Users from a partner company in…
- A company has a centralized security account that stores secrets in AWS Secrets Manager. Application teams in separate AWS accounts need to…
- A company has a centralized security account that stores database credentials in AWS Secrets Manager. Application teams in separate…
- A development team in Account A needs to access Amazon S3 resources in Account B. A developer sets up an IAM role in Account B with a trust…
- A company has an Amazon S3 bucket in Account A that stores data encrypted with SSE-KMS using a customer managed KMS key. A development team…
- A company stores database credentials in AWS Secrets Manager in a central security account. An application running on Amazon EC2 instances…
- A company has a development team in Account A that needs to access Amazon S3 buckets in Account B. A developer is implementing…
- Give compute a role, never embed long-lived access keys
Application code should carry an IAM role attached to the compute, not an access key ID and secret baked into code or config. Embedding static keys is the antipattern the exam punishes. With a role, the AWS SDK transparently obtains temporary credentials that auto-rotate and expire, so there is no long-lived secret to leak or rotate manually. Reach for the role mechanism that matches the compute: instance profile (EC2), task role (ECS), or execution role (Lambda).
Trap Storing IAM access keys in environment variables or config files on EC2/ECS/Lambda: attach a role instead and let the SDK fetch rotating STS credentials.
- Match the role type to the compute: instance profile, task role, execution role
Each compute service exposes role credentials differently and the names are tested as distractors. An EC2 instance profile wraps a role and the SDK fetches credentials from the Instance Metadata Service. Enforce IMDSv2 (
HttpTokens=required) to block SSRF-based credential theft. A Lambda execution role is set at function creation and auto-discovered by the SDK. For ECS, the task role is what the application code inside the container uses for its own AWS calls, distinct from the task execution role, which only lets the ECS agent pull images from ECR and ship logs to CloudWatch.Trap Putting the application's AWS permissions on the ECS task execution role: that role is for the agent (ECR pull, CloudWatch logs); app calls use the task role.
- STS sessions default to 1 hour, range 15 min to 12 h
When code switches identity it calls
sts:AssumeRole, which returns temporary credentials valid forDurationSeconds: 3600 seconds (1 hour) when omitted. The value may range from 900 seconds (15 minutes) up to the role's configured maximum session duration, which an admin can set anywhere from 1 to 12 hours. Requesting more than the role's maximum fails, so the role's ceiling caps the session.- Role chaining caps the session at 1 hour regardless of the role max
Role chaining (using one already-assumed role to assume a second role) always caps the new session at 1 hour, even if the target role's maximum session duration is set to 12 hours. This is a frequently tested gotcha: the 12-hour maximum applies to a directly assumed role, not to one reached by chaining from temporary credentials.
Trap Expecting a chained AssumeRole to honor a 12-hour role maximum: chaining silently caps the session at 1 hour.
3 questions test this
- A developer is building an application that uses role chaining to access resources in multiple AWS accounts. The application first assumes…
- A developer is building a data processing application that uses role chaining to access resources across multiple AWS accounts. The…
- A developer is implementing role chaining where an AWS Lambda function assumes Role A in Account X, and then uses those credentials to…
- A trust policy Principal of :root means the whole account, not the root user
Who may assume a role is governed by the role's trust policy (its resource-based policy). A trust policy
Principalofarn:aws:iam::<account-id>:rootdenotes account-level delegation: the entire account is trusted, NOT the AWS account root user. It means any IAM principal in that account whose own identity policy also permitssts:AssumeRolemay assume the role. To trust a single entity, name it explicitly, e.g.arn:aws:iam::<account-id>:role/Build.Trap Reading
:rootin a trust policy as the account's root user: it is account-wide delegation; the assuming principal still needs its own AssumeRole permission.- Require an ExternalId when a third party assumes your role
When a third-party SaaS assumes a role in your account, add a
Conditiononsts:ExternalIdin the role's trust policy and share that agreed value with the vendor. The vendor must pass the matchingExternalIdonAssumeRoleor the call fails. This defends against the confused-deputy problem, where an attacker tricks the trusted third party into using its access on your behalf without knowing your secret value.Trap Treating ExternalId as a secret password that authenticates the vendor, when it is a confused-deputy guard rather than a credential and offers no protection if the vendor is itself compromised.
8 questions test this
- A developer is building a multi-tenant SaaS application where a third-party company needs programmatic access to resources in the…
- A developer is building a multi-tenant SaaS application that needs to access resources in customer AWS accounts. Each customer creates an…
- A company hires a third-party SaaS provider to perform cost analysis on their AWS account. The company creates an IAM role in their account…
- A development team is configuring cross-account access for an application. The application in Account A needs to assume a role in Account B…
- A company requires that IAM roles used by applications in development accounts can only be assumed by specific CI/CD pipeline roles. The…
- A company uses an external third-party auditing service that requires access to read Amazon CloudWatch Logs in the company's AWS account.…
- A third-party monitoring company needs access to resources in a customer's AWS account. The customer creates an IAM role for the third…
- A company needs to grant a third-party vendor access to an S3 bucket in the company's AWS account. The vendor will access the bucket from…
- A permissions boundary or session policy caps permissions: it never grants them
Grants union, but ceilings intersect. Where a ceiling is present (a permissions boundary on the principal, or a session policy passed to
AssumeRole) effective permissions become the intersection of the identity's grants and that ceiling, so a session can never exceed what the role's own policy already allows. A boundary with no matching grant in the identity policy authorizes nothing; you still need an explicitAllowin the identity policy for any action.Trap Treating a permissions boundary or session policy as a way to add permissions: it only narrows; the underlying identity policy must still grant the action.
16 questions test this
- A developer is creating an application that uses AWS STS AssumeRole to provide temporary credentials to external contractors. The…
- A developer is implementing cross-account access where an application in Account A needs to access an Amazon S3 bucket in Account B. The…
- A security team wants to delegate IAM policy creation to developers while ensuring they cannot create policies that grant permissions…
- A company is implementing a permissions boundary to limit what IAM roles developers can create for their Lambda functions. The security…
- A company uses AWS STS AssumeRole to provide developers with temporary credentials to access production resources. The security team wants…
- A developer is implementing cross-account access for an application running on Amazon EC2 in Account A that needs to access Amazon DynamoDB…
- A company's security policy requires that all IAM roles created for Lambda functions can only access specific secrets in AWS Secrets…
- A developer is implementing an identity broker that authenticates users against a corporate Active Directory and provides AWS access. The…
- A developer is building a multi-tenant SaaS application where different tenants should have access to specific S3 buckets based on their…
- A development team at a financial services company needs to create IAM roles for Lambda functions that access customer data stored in AWS…
- A central IT team wants to allow developers to create IAM roles for their Lambda functions while ensuring the developers cannot grant more…
- A development team lead needs to allow developers to create IAM roles for their Lambda functions that access secrets stored in AWS Secrets…
- A development team needs permission to create IAM roles for their Lambda functions, but the security team wants to prevent privilege…
- A development team manager wants to allow developers to create IAM roles for their Lambda functions while ensuring that the developers…
- A developer is troubleshooting an issue where an IAM role has both an identity-based policy that allows s3:PutObject and a permissions…
- A development team lead needs to allow developers to create IAM roles for their Lambda functions while ensuring they cannot grant…
- A Cognito user pool authenticates users and issues three JWTs
A Cognito user pool is a user directory that performs authentication: users sign in and the pool returns an ID token, an access token (both JWTs you can verify against the pool's public JWKS), and a refresh token (opaque and encrypted, used only to mint new ID/access tokens). It answers "who is this user?": reach for a user pool when you need to sign your own application's end users in and protect your own API. The Hosted UI / managed login implements standard OAuth 2.0 grant flows (such as authorization code) so you do not hand-roll sign-in.
Trap Assuming the refresh token is a JWT you can verify against the JWKS like the others, when it is opaque and encrypted, usable only to mint new ID/access tokens.
- Send the access token to authorize an API, not the ID token
Of the user-pool JWTs, the ID token carries identity claims (email, name,
sub) and proves who the user is: consume it in your app to learn about the user, never to authorize a call. The access token is the OAuth 2.0 bearer token carrying scopes and groups, and it is what you present to a protected API to be authorized. The refresh token only mints new ID/access tokens and is never sent to your API.Trap Sending the Cognito ID token to an API authorizer: it proves identity, not authorization; pass the access token, whose scopes the authorizer checks.
- Use a Cognito identity pool to hand a signed-in user temporary AWS credentials
A Cognito identity pool (federated identities) performs authorization to AWS: it exchanges a verified login (from a user pool, or a third-party IdP like Google, Apple, Facebook, or any SAML/OIDC provider) for temporary AWS credentials from STS, scoped by an IAM role. Reach for it only when a signed-in user must call an AWS service such as S3 or DynamoDB directly from the client. Identity pools also support an unauthenticated (guest) role, granting limited access to users who have not signed in.
Trap Reaching for an identity pool just to authenticate users or protect your own API: that is the user pool's job; the identity pool exists to vend AWS credentials.
- User pool authenticates, identity pool federates to AWS: don't swap them
The decision rule the exam relentlessly tests: need to authenticate a user and protect your own API? Use a user pool and validate the access token. Need to give that user scoped AWS credentials to hit an AWS service directly? Use an identity pool, which returns STS credentials. Used together, the user pool authenticates and issues JWTs, then the identity pool swaps a token via STS for AWS credentials.
Trap Picking a user pool for "let the signed-in user write to S3 directly": that needs an identity pool's STS credentials, not just a JWT.
- Cognito is for application users; IAM Identity Center is for your workforce
Match the identity service to the audience. Amazon Cognito signs in an application's external end users (customers of your app). IAM Identity Center signs in your own workforce: employees needing access to AWS accounts and business applications. The two are not interchangeable, and a scenario that names one where the other belongs is a deliberate distractor.
Trap Using Cognito for employee access to AWS accounts (or Identity Center for app customers): Cognito = app end users, Identity Center = workforce.
- A Cognito or JWT authorizer gates a route declaratively, no code
An API Gateway Cognito authorizer (REST API) or JWT authorizer (HTTP API) validates an incoming bearer JWT's signature, expiry, and scopes/claims and allows or denies the route with no custom code. Point it at a Cognito user pool or any OIDC issuer and pass the access token. This is the default answer when sign-in is already Cognito and you only need standard token validation at the edge.
Trap Writing a Lambda authorizer to validate a standard Cognito/OIDC JWT, when the built-in Cognito or JWT authorizer does signature, expiry, and scope checks declaratively with no code.
2 questions test this
- Use a Lambda authorizer for non-JWT tokens or bespoke logic
A Lambda authorizer (formerly custom authorizer) runs your function to return an allow/deny decision (an IAM policy document, or a simple boolean for HTTP APIs) and is the right choice for validating an opaque or non-Cognito token, or applying custom logic a declarative authorizer can't express. A TOKEN authorizer receives only the bearer token from a single header; a REQUEST authorizer receives the full request context (headers, query string, path, stage variables) and is needed when the decision depends on more than one input. Results can be cached by TTL to avoid invoking the function on every request.
Trap Choosing a TOKEN Lambda authorizer when the decision needs query strings or multiple headers: TOKEN sees only one header's token; use REQUEST for full request context.
8 questions test this
- A developer is building a REST API using Amazon API Gateway with a Lambda authorizer. The authorizer validates JWT tokens passed in the…
- A company uses Amazon API Gateway REST API with a Lambda TOKEN authorizer to protect their APIs. The authorizer validates JWT tokens from…
- A development team is implementing API authentication for an HTTP API using Amazon API Gateway. The team wants to use a Lambda authorizer…
- A financial services company is building a REST API using Amazon API Gateway. The company uses an external OAuth 2.0 identity provider to…
- A company is building a REST API using Amazon API Gateway with Lambda authorizer for authentication. The development team notices that when…
- A company is building a microservices architecture using Amazon API Gateway REST APIs. The development team needs to implement custom…
- A developer needs to implement fine-grained access control for an Amazon API Gateway REST API using a Lambda authorizer. The authorizer…
- A company is building an API Gateway REST API with a Lambda REQUEST authorizer. The authorizer must validate requests based on a…
- Use AWS_IAM authorization for SigV4 callers, not browser end users
API Gateway IAM authorization (
AWS_IAM) requires the caller to sign the request with SigV4 using IAM credentials, and the request is evaluated through the same identity/resource-policy model as any AWS API call. It fits service-to-service or internal callers that already hold IAM credentials, not browser or mobile end users, who carry JWTs and should use a Cognito/JWT or Lambda authorizer instead.Trap Choosing AWS_IAM authorization for browser or mobile end users, who hold JWTs rather than signable IAM credentials; SigV4/IAM auth fits service-to-service callers.
- OIDC is the identity layer on top of OAuth 2.0's authorization framework
OAuth 2.0 is the authorization framework (delegating access via tokens); OIDC adds the identity (authentication) layer on top. Mapped to Cognito: the ID token is the OIDC artifact answering who the user is, and the access token is the OAuth 2.0 artifact carrying scopes for what the bearer may do. A JWT/Cognito authorizer enforces the access token's scopes at the API edge.
Trap Treating OAuth 2.0 itself as an authentication protocol, when OAuth 2.0 handles authorization and OIDC is the identity layer added on top to authenticate the user.
- Edge authorizers gate the route; fine-grained rules go in code
API Gateway authorizers and IAM gate whether a caller may reach a route or action: they do not express per-resource business rules like "can THIS user edit THIS document?". For fine-grained, per-request decisions beyond what scopes capture, validate claims in your application code or use Amazon Verified Permissions. Don't expect a scope check at the edge to enforce row-level ownership.
Trap Expecting an edge scope or JWT authorizer to enforce row-level ownership like "can this user edit this document", when per-resource rules belong in code or Verified Permissions.
- Apply least privilege and prefer MultiFactorAuthPresent for fresh-MFA checks
Each policy should grant only the actions and resources an identity needs, narrowed with
Conditionkeys where possible. When gating a sensitive action on MFA, know the two condition keys differ:aws:MultiFactorAuthPresentis true only when the CURRENT credentials were obtained with MFA, whileaws:MultiFactorAuthAgemeasures how long ago that MFA happened. Use the age key when you need recency, not just presence.Trap Relying on
aws:MultiFactorAuthAgeto require MFA at all: the age key is absent (so a deny-on-absence can misfire) when no MFA occurred;aws:MultiFactorAuthPresentchecks that MFA happened, the age key checks how recently.- Principal: "*" on a resource or trust policy means anyone, anywhere
A
Principalof"*"on a resource-based or trust policy grants the action to any principal in any account (effectively public) and is almost always the wrong answer on a security scenario. Scope access instead to a specific principal ARN, a specific account, oraws:PrincipalOrgIDto bound it to your organization. The exam dangles"*"as a tempting "it just works" option.Trap Accepting
Principal: "*"to make access "just work": it exposes the resource to every AWS account; scope to a principal ARN, account, or PrincipalOrgID.- ABAC compares aws:PrincipalTag to aws:ResourceTag in a StringEquals condition
Attribute-based access control grants access only when a tag on the calling principal matches a tag on the target resource. The policy uses a
ConditionwithStringEqualscomparingaws:ResourceTag/<Key>to the policy variable${aws:PrincipalTag/<Key>}(for exampleteamorEnvironment) so one policy scales to every team without per-team rules. When the principal is an IAM user rather than a tagged role,${aws:username}is the matching variable against the resource's owner tag.Trap Hard-coding a tag value as a literal string instead of the
${aws:PrincipalTag/...}policy variable: ABAC's whole point is the dynamic principal-vs-resource tag comparison.5 questions test this
- A company uses Amazon EC2 instances for development workloads. The security team requires that developers can only start and stop EC2…
- A company implements attribute-based access control (ABAC) to manage access to EC2 instances across multiple development teams. Each team…
- A developer is creating an IAM policy to allow EC2 instances to access specific resources based on their tags. The policy should allow…
- A company implements attribute-based access control (ABAC) to manage access to secrets stored in AWS Secrets Manager. Development teams…
- A developer is implementing attribute-based access control (ABAC) for a microservices application. The application uses IAM roles with tags…
- A Lambda authorizer must return principalId plus a policyDocument, with context values stringified
A REST API Lambda authorizer's output must include a
principalIdand apolicyDocument(an IAM policy withexecute-api:Invokestatements); omit either and API Gateway returns 500, not 403. Anycontextmap it returns may hold only stringified primitives: you cannot set a JSON object or array as a context value. The backend reads those values via$context.authorizer.<key>.Trap Returning a JSON object or array in the authorizer's
contextmap: every context value must be a stringified primitive (string, number, boolean) or the request fails.5 questions test this
- A developer is troubleshooting an API Gateway REST API with a Lambda authorizer. When clients send requests with valid authorization…
- A developer is configuring a Lambda authorizer for an Amazon API Gateway REST API. The Lambda authorizer function validates incoming…
- A company has an Amazon API Gateway REST API with a TOKEN-type Lambda authorizer. The authorizer validates OAuth tokens from an external…
- A developer is implementing a Lambda authorizer for an API Gateway REST API that validates JWT tokens. The authorizer needs to pass user…
- A company is building a microservices architecture using Amazon API Gateway REST APIs. The development team needs to implement custom…
Encryption with AWS Services
Read full chapterUnlock with Premium — includes all practice exams and the complete study guide.
Sensitive Data Management
Read full chapterUnlock with Premium — includes all practice exams and the complete study guide.
Deployment
Application Artifacts
Read full chapterCheat sheet
Sharp facts the exam loves — scan these before test day.
- A deployment artifact is self-contained: it carries every runtime dependency
A deployment artifact is the immutable bundle you hand to AWS to run, and it must include the code plus every library the code imports at runtime, because the managed execution environment adds nothing you did not package. The one deliberate exception is environment-specific configuration and secrets, which are injected at deploy or run time so the same bundle promotes unchanged across dev, test, and prod. Configuration files and other static assets do travel inside the package; only per-environment values and credentials stay out.
Trap Assuming the managed runtime supplies common third-party libraries so you can leave them out of the bundle. Only the language's standard library and AWS SDK are present, so any other dependency you import must be packaged.
- Match the Lambda .zip to the function's runtime AND architecture
A Lambda
.ziparchive holds your handler plus third-party libraries compiled for the function's runtime and CPU architecture: x86_64 or arm64. A package built for the wrong architecture passes upload but fails at invoke, because native dependencies are architecture-specific. When you switch a function between arm64 and x86_64, rebuild the dependencies for the new architecture.Trap Assuming a working x86_64
.zipruns unchanged on arm64. Native extensions are compiled per-architecture and break at invoke, not at upload.- A Lambda .zip is capped at 50 MB direct upload and 250 MB unzipped
A Lambda
.zipis limited to 50 MB when uploaded directly through the API, SDK, or console, and to 250 MB unzipped, a ceiling that includes the function code plus all attached layers and custom runtimes. A.ziplarger than 50 MB cannot be uploaded inline; you upload it to Amazon S3 first and point Lambda at the S3 object. The 250 MB unzipped figure is the hard ceiling on total uncompressed size.Trap Trying to push a
.zipover 50 MB straight through the console or API. Anything larger must be staged in S3 and referenced from there.3 questions test this
- A developer is creating an AWS Lambda function that requires dependencies totaling 300 MB when unzipped. The application must use Python…
- A developer is building a Python Lambda function that requires machine learning libraries totaling 400 MB when unzipped. The function must…
- A developer is troubleshooting a Lambda function deployment. The function uses three Lambda layers and the deployment fails with an error…
- Use a container image in ECR when dependencies exceed the .zip limits
When a function's dependencies, native binaries, machine-learning models, or custom runtime exceed the
.zipceiling, package it as a container image instead. Lambda accepts an image up to 10 GB uncompressed, stored in Amazon ECR (Elastic Container Registry, AWS's managed image registry). The image bakes in its own dependencies, so it has no layers. Reach for.zipfor small, pure-language or prebuilt-dependency functions; reach for a container image when size or native tooling rules.zipout.Trap Picking a
.zipfor a large ML model or native-binary workload. It blows past the 250 MB unzipped cap, where a 10 GB container image is the intended path.- A Lambda function's package type is fixed at creation
You choose
.zipor container image when you create a Lambda function, and you cannot switch a function from one package type to the other afterward. To change type you create a new function. The package type is an immutable property, unlike code or configuration, which you can update in place.Trap Assuming you can convert an existing
.zipfunction to a container image in place. The type is locked at creation, so you must stand up a new function.- Lambda layers factor shared dependencies out of each function's .zip
A Lambda layer is a separate
.zipof libraries or a runtime that multiple functions reference, so a common dependency is uploaded and stored once rather than rebundled into every function. A function can attach up to 5 layers. Layers cut duplication and per-function upload size, but a layer's unzipped contents still count toward the same 250 MB unzipped quota as the function code. They reduce duplication, not the total uncompressed ceiling. Layers apply only to.zipfunctions; a container-image function bakes its dependencies into the image and has no layers.Trap Treating layers as a way around the 250 MB limit. A layer's unzipped size counts toward that same ceiling.
6 questions test this
- A company uses AWS Lambda with Python for multiple functions that share common data processing libraries. The shared libraries are…
- A developer is configuring an AWS Lambda function that requires three custom layers and two layers provided by AWS Partners. After adding…
- A development team manages 15 Python Lambda functions that share common dependencies including a custom logging utility and several…
- A company has multiple Lambda functions written in Node.js that share common utility libraries and the AWS SDK. The developers want to…
- A developer is creating an AWS Lambda function using Python that requires several third-party libraries totaling 180 MB when unzipped. The…
- A developer is troubleshooting a Lambda function deployment. The function uses three Lambda layers and the deployment fails with an error…
- SAM is an extension of CloudFormation, not a separate deployment engine
An AWS SAM (Serverless Application Model) template is an extension of CloudFormation: it adds shorthand serverless resource types such as
AWS::Serverless::Function, and those expand into standard CloudFormation resources at deploy time. Because SAM resources sit beside plain CloudFormation resources in one template, anything you can write in raw CloudFormation you can also write in a SAM template. There is no separate SAM provisioning service to choose instead of CloudFormation.Trap Treating "SAM vs CloudFormation" as mutually exclusive engines. SAM is CloudFormation plus a macro, so it is never an alternative to it.
- Transform: AWS::Serverless-2016-10-31 is the macro that turns a template into SAM
The line
Transform: AWS::Serverless-2016-10-31at the top of a template is the CloudFormation macro that marks it as a SAM template and expands the shorthand serverless resources into standard CloudFormation resources during deployment. Spotting that exact Transform value (or anAWS::Serverless::*resource type) is how you identify a template as SAM rather than plain CloudFormation.- sam build, package, deploy map onto how the artifact reaches AWS
The SAM CLI ships an artifact in three steps.
sam buildresolves and installs each function's dependencies into a local.aws-sam/builddirectory. This is where the self-contained artifact is assembled.sam packageuploads those built artifacts to Amazon S3 (or to Amazon ECR for container images) and rewrites the template's local code paths to the uploaded URIs.sam deploysubmits that rewritten template to CloudFormation to create or update the stack, and it runs the package step for you if you have not already.Trap Thinking
sam buildis the step that uploads the artifact to S3. Build only assembles dependencies locally;sam package(orsam deploy) is what uploads to S3 and rewrites the code URIs.4 questions test this
- A developer modified the code for a Lambda function in their AWS SAM application. The application was previously built using sam build,…
- A developer is testing an AWS Lambda function locally using the AWS SAM CLI before deploying to AWS. The developer updates the function…
- A developer has made code changes to a Lambda function in a SAM application. The application was previously built using sam build which…
- A developer is building a serverless application using AWS SAM. The application includes multiple Lambda functions that are triggered by…
- Know what Parameters, Mappings, and Outputs do in a template
A CloudFormation template uses Parameters as the per-environment input knobs (instance size, table name, log level) that vary one template into different stacks; Mappings as static lookup tables resolved at deploy time (for example region to AMI ID); and Outputs to export values such as an API URL or bucket name for other stacks or operators to consume. Passing different Parameter values is what lets the same template produce a dev stack or a prod stack without editing it.
Trap Using Mappings to feed per-environment values like instance size or table name. Mappings are static lookup tables, so caller-supplied per-environment differences belong in Parameters.
- Ref, Fn::GetAtt, and Fn::Sub each wire templates differently
CloudFormation intrinsic functions connect resources.
Refreturns a resource's primary identifier (or a parameter's value), typically the name or ID.Fn::GetAttreturns a specific attribute of a resource, such as a bucket's ARN or a DynamoDB table's stream ARN, whichRefdoes not give you.Fn::Subsubstitutes variables into a string, letting you interpolate references inline. PickFn::GetAttwhen you need an attribute like an ARN; pickRefwhen the primary ID or a parameter value is enough.Trap Using
Refto get a resource's ARN.Refreturns the primary identifier, so an ARN or other attribute needsFn::GetAtt.- Use a change set to preview a stack update before executing it
A change set is a preview of exactly what a stack update would add, modify, or delete, generated before you execute it, the safe way to update a stack because you confirm the blast radius first, including any resource replacements. When a question asks how to see the impact of a template change before applying it, the answer is a change set, not a blind stack update.
Trap Running a plain stack update when the stem wants a preview of the changes. Only a change set shows what will change before you commit.
- Nested stacks compose large architectures from reusable child templates
Nested stacks let one parent template reference child templates as resources, so a large architecture is built from reusable, modular pieces instead of one monolithic file. Each child is its own stack the parent provisions, which keeps templates within size limits and lets common patterns (a standard VPC, a logging bucket) be reused across stacks.
Trap Reaching for cross-stack references (Export/Fn::ImportValue) when the goal is to provision and manage child templates as one unit. That lifecycle composition is what nested stacks provide, while exports only share values between independently managed stacks.
- Drift detection reports where a stack diverged from its template
Drift detection compares a stack's actual resource configuration against what its template declares and reports any differences caused by out-of-band changes, for example, someone editing a resource directly in the console or CLI. It is the tool for catching configuration that no longer matches the source-of-truth template, not for previewing a planned update.
Trap Reaching for a change set to find manual console edits. Change sets preview intended updates, while drift detection surfaces unintended out-of-band changes.
- Know where each artifact type is stored
Lambda
.zipartifacts and CloudFormation/SAM templates are stored in Amazon S3; container images live in Amazon ECR; and your language packages (the npm, PyPI, or Maven dependencies a build pulls in) can be hosted privately in AWS CodeArtifact, AWS's managed package repository. CodeArtifact gives builds a controlled, versioned source for dependencies rather than pulling them from public registries directly.Trap Reaching for S3 or ECR to host private npm, PyPI, or Maven packages. Hosting those package registries is CodeArtifact's job, while S3 holds
.zip/templates and ECR holds container images.- Use AppConfig to change behavior without redeploying code
AWS AppConfig (a feature of AWS Systems Manager) decouples configuration from code so you can change application behavior (a feature flag, an operational setting) without a code deployment. Its defining feature is validators that check the configuration is syntactically and semantically correct before a rollout, so a bad config never reaches the running application. It can source data from its own hosted store, SSM Parameter Store, Secrets Manager, or S3. Reach for AppConfig when the stem stresses changing behavior at runtime or validating config before it goes live.
Trap Choosing plain Parameter Store when the question stresses validating config before rollout or toggling a feature flag without a deploy. That validation-and-rollout machinery is AppConfig, not a bare named value.
- Use SSM Parameter Store for simple named config values
SSM Parameter Store holds plain configuration values an application fetches at runtime by name, such as an endpoint URL or a numeric setting. A
SecureStringparameter additionally encrypts the value with AWS KMS, which is how you store a sensitive value without Secrets Manager. Choose Parameter Store when you just need a named value retrieved at runtime, not the validation-and-rollout machinery of AppConfig.Trap Reaching for Secrets Manager for any sensitive value when no rotation or generation is needed. A KMS-encrypted
SecureStringparameter stores a secret in Parameter Store at lower cost.- Build the artifact once; inject per-environment differences at deploy and run time
Bake environment-specific values into the artifact and you must build a separate bundle per environment, which breaks the guarantee that what you tested is byte-for-byte what you ship. Instead build the artifact once and vary it externally: CloudFormation/SAM Parameters supply the deploy-time differences, while AppConfig and Parameter Store supply the run-time differences. The artifact and its template stay identical across dev, test, and prod.
- Never package secrets into the artifact: reference them at runtime
Database passwords, API keys, and other secrets are never packaged into the deployment artifact; the bundle carries only the code that fetches the secret. At runtime the application reads the value from AWS Secrets Manager or an SSM
SecureStringparameter. Embedding the secret in the package leaks it into every copy of the artifact and ties the build to one environment.Trap Putting a database password or API key in an environment variable baked into the package. It leaks into the artifact; fetch it at runtime from Secrets Manager or a
SecureStringinstead.- Elastic Beanstalk config files must be .config files inside an .ebextensions folder at the bundle root
To customize an Elastic Beanstalk environment (install packages, set options), place YAML or JSON configuration files with the .config extension in a folder named exactly .ebextensions (leading dot required) at the root of the source bundle. Files outside that folder, without the .config extension, or in a folder misnamed 'ebextensions' are silently ignored. When zipping, include hidden dot-folders (for example zip -r app.zip * .[^.]*) and produce a bundle with no parent folder so .ebextensions sits at the root.
Trap Naming the folder 'ebextensions' without the leading dot, or zipping with a wrapping parent folder. Elastic Beanstalk then ignores the config files entirely.
6 questions test this
- A developer is creating a source bundle for an AWS Elastic Beanstalk Node.js application. The application uses custom environment…
- A developer is preparing a source bundle for deployment to AWS Elastic Beanstalk. The application includes custom environment…
- A developer is configuring an Elastic Beanstalk environment and needs to customize the EC2 instances with additional packages and…
- A development team is preparing to deploy a Java web application to AWS Elastic Beanstalk. The application consists of several components…
- A developer is customizing an AWS Elastic Beanstalk environment by adding configuration files to install packages and modify environment…
- A developer needs to install additional packages and configure environment settings during deployment of an AWS Elastic Beanstalk…
- Elastic Beanstalk uses a Procfile for multiple processes and cron.yaml for worker periodic tasks
An Elastic Beanstalk source bundle is a single ZIP (or a WAR for Java) with special files at its root. A Procfile declares multiple long-running processes (the main one must be named 'web' and is listed first) and Elastic Beanstalk restarts any that exit; it is also how you pass JVM options per Java process. A worker environment's periodic background jobs are defined in a cron.yaml at the root, each with a name, URL path, and a CRON schedule. The multi-container ECS-managed Docker platform instead uses a Dockerrun.aws.json v2 at the root (with a .dockercfg in S3 for private-registry auth).
Trap Hand-rolling a startup script for several processes. Elastic Beanstalk monitors and restarts processes only when they are declared in a root Procfile (web first).
4 questions test this
- A developer is creating a Java SE application source bundle for deployment to AWS Elastic Beanstalk. The application requires running…
- A developer is packaging a Java SE application for deployment to AWS Elastic Beanstalk. The application consists of multiple JAR files that…
- A company is using AWS Elastic Beanstalk with the ECS managed Docker platform to run multiple containers on each EC2 instance. The…
- A development team is deploying a worker environment to AWS Elastic Beanstalk that needs to run periodic background tasks. The tasks should…
- An Elastic Beanstalk application-version source bundle must be in-region and readable
When you create an Elastic Beanstalk application version from a source bundle in S3, the bucket must be in the same AWS Region as the environment, or the call fails with an invalid-S3-location error. If the bundle lives in a custom bucket with a restrictive policy, also grant the IAM identity creating the version s3:GetObject (and s3:GetObjectVersion) on the bundle object, or the create fails with access denied.
Trap Assuming a valid, existing S3 bundle is enough. A different-Region bucket fails as 'invalid S3 location', and a restrictive bucket policy fails as access denied without explicit s3:GetObject.
- An Elastic Beanstalk application version lifecycle policy prunes old versions automatically
Elastic Beanstalk caps application versions per Region; to avoid hitting the quota, configure an application version lifecycle policy that auto-deletes old versions by a MaxCount rule (keep the N most recent) or a MaxAge rule. Set DeleteSourceFromS3 to true to also remove the source bundles from S3, or false to keep them for compliance. Elastic Beanstalk never deletes a version currently deployed to any environment, and it applies the policy each time you create a new version.
Trap Worrying a lifecycle policy will remove an in-use version. Elastic Beanstalk protects versions deployed to any environment; DeleteSourceFromS3 only controls whether the S3 bundle is also deleted.
4 questions test this
- A company has been deploying frequent updates to their Elastic Beanstalk application and has received an error indicating they have reached…
- A company runs multiple applications on AWS Elastic Beanstalk in a single AWS Region. The development team frequently deploys new…
- A company uses AWS Elastic Beanstalk to deploy a Java application. Over time, the development team has created hundreds of application…
- A company has been using AWS Elastic Beanstalk for over two years and has accumulated more than 800 application versions across 10…
- A Python Lambda layer must put dependencies under a python/ directory at the .zip root
Lambda extracts layer contents into /opt, and the Python runtime searches /opt/python for imports, so a Python layer .zip must contain a top-level 'python/' directory with the libraries inside it. A layer whose modules sit at the archive root (or under any other folder) extracts to the wrong place and the function fails with 'Unable to import module' / ModuleNotFoundError even though the libraries are present.
Trap Zipping the dependencies at the layer root. Python only finds them under /opt/python, so they must be wrapped in a top-level python/ directory.
4 questions test this
- A developer is creating a Lambda layer to share common Python dependencies across multiple Lambda functions. The layer must contain the…
- A development team manages 15 Python Lambda functions that share common dependencies including a custom logging utility and several…
- A developer is creating an AWS Lambda function using Python that requires several third-party libraries totaling 180 MB when unzipped. The…
- A developer is creating an AWS Lambda layer to share common Python utilities across multiple Lambda functions. The developer creates a .zip…
- Override a CloudFormation stack policy for one update with --stack-policy-during-update-body
A stack policy that denies updates to a protected resource (such as an RDS database) blocks even an authorized urgent change. To update the protected resource for a single operation without permanently editing the stack policy, run update-stack with --stack-policy-during-update-body (or --stack-policy-during-update-url) specifying a temporary policy that allows the needed action. The override applies only to that update; the original stack policy stays intact afterward.
Trap Calling SetStackPolicy to permanently loosen the policy for one urgent change. The temporary --stack-policy-during-update-body override leaves the original policy unchanged.
4 questions test this
- A developer needs to update a protected resource in an AWS CloudFormation stack that has a stack policy preventing all update operations on…
- A developer needs to perform an emergency update to an Amazon DynamoDB table that is protected by a CloudFormation stack policy. The stack…
- A developer has a CloudFormation stack with a stack policy that prevents updates to a production database. During an emergency, the…
- A company uses AWS CloudFormation to manage critical production infrastructure including an Amazon RDS database and several Amazon EC2…
- CloudFormation stack policies gate on Update:Modify, Update:Replace, and Update:Delete
Stack policy statements use granular update actions: Update:Modify (in-place changes that keep the physical ID), Update:Replace (changes that recreate the resource with a new physical ID), and Update:Delete (removal). To protect a resource from being recreated or removed while still allowing harmless in-place edits, Deny Update:Replace and Update:Delete (or Allow Update:Modify and Deny Update:Replace). When a stack policy is set, all resources are protected by default, so guarding one resource means an Allow for the rest plus a targeted Deny.
Trap Denying all Update:* to protect a resource when in-place changes must still be allowed. Deny only Update:Replace and Update:Delete so Update:Modify edits still go through.
3 questions test this
- A company uses AWS CloudFormation to manage its production infrastructure. A developer needs to protect a critical Amazon RDS database…
- A development team uses AWS CloudFormation to deploy a production stack containing an Amazon RDS database, an Amazon EC2 Auto Scaling…
- A company uses AWS CloudFormation to deploy production infrastructure. The company requires that specific resource types, such as…
- Continuous CloudFormation drift detection uses the AWS Config managed rule plus EventBridge and SNS
For scheduled, continuous drift detection across stacks and accounts, enable the AWS Config managed rule cloudformation-stack-drift-detection-check: it runs DetectStackDrift, marking a stack COMPLIANT when IN_SYNC and NON_COMPLIANT when DRIFTED. Pair it with an EventBridge rule matching the Config compliance-change events to notify via SNS. This is the low-overhead automated answer, versus the manual CLI sequence detect-stack-drift then poll describe-stack-drift-detection-status then describe-stack-resource-drifts.
Trap Scripting repeated detect-stack-drift CLI calls for ongoing monitoring. The low-overhead continuous solution is the AWS Config managed rule with EventBridge and SNS.
4 questions test this
- A company uses AWS CloudFormation to deploy infrastructure across multiple accounts. Operations engineers occasionally make manual changes…
- A developer has a CloudFormation stack deployed in production and needs to implement automated compliance checking to detect when resources…
- A developer needs to automate detection of configuration changes made outside of AWS CloudFormation to deployed stacks across multiple…
- A company needs to continuously monitor AWS CloudFormation stacks for configuration drift across multiple AWS accounts and Regions. When…
- Protect versioned S3 artifacts with Object Lock, MFA Delete, and noncurrent-version lifecycle rules
On a versioning-enabled artifact bucket, choose the protection by requirement. Object Lock governance mode blocks deletes for most users but lets holders of s3:BypassGovernanceRetention override; compliance mode blocks deletes for everyone including root until retention expires, and supports legal holds. MFA Delete (enabled only by the root account via CLI/API) requires MFA to permanently delete a version or change versioning state. To prune by version, NoncurrentVersionExpiration with NewerNoncurrentVersions keeps the N most recent noncurrent versions and expires older ones after NoncurrentDays, and NoncurrentVersionTransition moves them to a cheaper class first.
Trap Reaching for governance mode when the rule says even the root account must never delete. That requires compliance mode; governance mode is overridable with the bypass permission.
5 questions test this
- A company stores deployment artifacts for multiple application versions in a versioning-enabled Amazon S3 bucket. To comply with regulatory…
- A company uses AWS CodePipeline for continuous deployment. The pipeline stores build artifacts in an Amazon S3 bucket. A developer notices…
- A company uses an Amazon S3 bucket with versioning enabled to store deployment artifacts for a CI/CD pipeline. The security team requires…
- A financial services company stores critical deployment artifacts in an Amazon S3 bucket. Regulatory requirements mandate that these…
- A development team stores application deployment artifacts in an Amazon S3 bucket with versioning enabled. The team wants to optimize…
- ECR enhanced scanning uses Amazon Inspector for continuous OS + language-package vulnerability scans
ECR basic scanning covers only operating-system packages. To scan both OS and programming-language dependencies (Python, Java, etc.) and to keep re-scanning images as new CVEs are published, enable enhanced scanning on the private registry with a continuous scan filter. It integrates with Amazon Inspector. Inspector emits scan-finding events to EventBridge, so an EventBridge rule to SNS gives automated alerts when new findings appear.
Trap Choosing basic scanning for language-dependency CVEs or ongoing monitoring. Basic scans only OS packages once; continuous OS+language scanning requires enhanced scanning via Inspector.
4 questions test this
- A developer is configuring Amazon ECR for a production environment. The company requires continuous vulnerability scanning of container…
- A development team uses Amazon ECR to store container images for their microservices application. The security team requires that all…
- A company runs containerized applications on Amazon ECS with AWS Fargate. The security team requires that all container images in Amazon…
- A development team is building a containerized Python application that uses third-party packages from PyPI. The security team requires the…
Development Environment Testing
Read full chapterUnlock with Premium — includes all practice exams and the complete study guide.
Automated Deployment Testing
Read full chapterUnlock with Premium — includes all practice exams and the complete study guide.
CI/CD Deployment
Read full chapterUnlock with Premium — includes all practice exams and the complete study guide.
Troubleshooting and Optimization
Root Cause Analysis
Read full chapterCheat sheet
Sharp facts the exam loves — scan these before test day.
- Match the symptom to the question, and the right telemetry signal falls out
AWS root cause analysis reads four complementary signals, each answering exactly one question: CloudWatch Logs answers "what happened in this one request?", CloudWatch metrics answer "how often, how much, is it trending?", X-Ray answers "where in the call chain did time or errors build up?", and CloudTrail answers "who called which AWS API, when, from where?". The DVA-C02 reflex is this mapping itself, so when a stem describes a symptom, name the question first and the service follows. A spike on a dashboard is a metrics question, a single failed transaction is a logs question, slow end-to-end latency across services is a trace question, and an unexplained config or permission change is a CloudTrail question.
Trap Grepping raw logs by hand to judge whether errors are trending up. That is a metrics job, and scanning log text for a rate is slow and error-prone.
- Reach for CloudWatch Logs when you need the exact error on one request
CloudWatch Logs holds the line-level event record: the timestamped text or JSON your code and managed services emit into a log group such as
/aws/lambda/<function-name>. It is the signal that tells you what exactly happened inside a single failed transaction, down to the stack trace or message. Use it when you already know which request failed and need its precise cause, rather than when you are trying to spot a trend across many requests, which is a metrics question.Trap Reaching for CloudWatch Logs to spot a trend across many requests, when a rate or count over time is a metrics question and Logs answers what happened inside one specific request.
- Use Logs Insights as the reactive hunt for one request's failure
CloudWatch Logs Insights is an interactive query engine over your log groups with a purpose-built query language built from
fields,filter,stats,sort, andlimitcommands, run ad hoc during an investigation to surface the exact events behind a failure. It can search multiple log groups in one query, and a running query is stopped after 60 minutes if it has not completed. Reach for it when the question is "what was the error on request X?", the reactive hunt, in contrast to a metric filter, which is a standing rule that watches every new log event.Trap Standing up a Logs Insights query to continuously watch for and alert on new failures, when Insights is an on-demand reactive hunt and a metric filter plus an alarm is the proactive standing rule.
7 questions test this
- A developer is troubleshooting an Amazon API Gateway REST API that returns intermittent 504 Gateway Timeout errors. The developer has…
- A developer operates a microservices application on Amazon ECS with Fargate. The application uses the awslogs log driver to send container…
- A developer is troubleshooting a microservices application running on AWS Lambda. The application generates structured JSON logs containing…
- A developer is troubleshooting an AWS Lambda function that is experiencing intermittent timeout errors. The developer needs to identify…
- A company's API Gateway REST API is experiencing high 4XXError rates according to CloudWatch metrics. The development team suspects that…
- A developer is troubleshooting intermittent timeout errors in an AWS Lambda function that processes orders from an Amazon SQS queue. The…
- A developer is troubleshooting a Python Lambda function that processes payment transactions. The application uses structured JSON logging…
- Convert a log pattern into a metric with a metric filter, then alarm on it
A metric filter is a standing rule on a log group that scans every incoming event for a pattern (say the term
ERRORor a5xxstatus) and emits a numeric CloudWatch metric you can alarm on. This is how you turn unstructured log text into a measurable trend that pages you proactively, rather than discovering the problem only when you go hunting. Logs Insights is the reactive query you run after the fact; a metric filter plus an alarm is the proactive trigger set up in advance.Trap Trying to detect a rising error rate by repeatedly running a Logs Insights query: use a metric filter feeding an alarm so the trend pages you instead of you polling for it.
- A CloudWatch metric is identified by its namespace plus dimensions
A metric is a numeric time series (error count, p99 latency, throttle count) identified by a namespace that isolates one service's metrics (for example
AWS/Lambda) plus a set of dimensions, which are name/value pairs such asFunctionName=checkoutthat scope the series to one resource. Dimensions are how you narrow a chart from "all functions" down to the single function that is misbehaving. You set alarms on metrics, and a metric spike bounds the time window you then drill into with logs and traces.Trap Treating a namespace/dimension pair as interchangeable with another after the fact, forgetting that a dimension is part of a metric's identity, so an alarm created on a specific dimension combination does not retroactively cover series you never published with those exact dimensions.
4 questions test this
- A company uses Amazon API Gateway to expose a REST API. The operations team notices a spike in the 4XXError CloudWatch metric but cannot…
- A developer notices that an Amazon API Gateway REST API is returning intermittent 429 Too Many Requests errors to some clients during peak…
- A development team is investigating intermittent 429 Too Many Requests errors returned by their Amazon API Gateway REST API. The team wants…
- A development team manages an Amazon API Gateway REST API that serves multiple client applications. The team notices a spike in 4XXError…
- A flat Lambda Errors line with rising Throttles means concurrency is exhausted, not broken code
Lambda's Errors metric counts only function errors (an unhandled exception or a timeout raised inside your handler) so a rising Errors line points at your code. Throttles is a separate metric that counts invocations rejected because concurrency was exhausted, surfaced as
TooManyRequestsException/ HTTP429, and a throttle does NOT increment Errors. So if Errors stays flat while Throttles climb, the fix is to raise reserved or provisioned concurrency or the account concurrency limit, not to read your handler code.Trap Debugging handler logic because invocations are failing, when the Errors metric is flat and only Throttles is rising. A throttle is a concurrency limit, not a code fault.
- Watch Lambda Duration climbing toward the timeout before it turns into errors
Lambda's Duration metric measures execution time per invocation, and it is the early-warning signal for a performance regression: a Duration line trending up toward the configured timeout is what eventually turns into function errors once invocations actually hit the ceiling and time out. Treat a rising Duration as the metric to investigate proactively, since by the time it shows up as timeouts in the Errors metric the user impact has already begun.
Trap Waiting for the Errors metric to rise before investigating a slowdown, since by then invocations are already timing out, whereas a Duration line climbing toward the configured timeout warns you while there is still headroom to act.
- Distinguish a function error from an invocation error before you touch code
A function error is raised inside your handler (an unhandled exception or a timeout) and is the case where you actually debug your code. An invocation error happens before or around your code: a throttle when concurrency is exhausted (
TooManyRequestsException/429), or a permission/configuration failure such as the caller lackinglambda:InvokeFunction. Read the error type and the metric first, because the two classes point at different layers: fix the handler for a function error, but fix concurrency limits or IAM permissions for an invocation error.Trap Reading application logs to fix a "not authorized to perform lambda:InvokeFunction" failure. That is an invocation-level permission problem, not a bug in your handler.
- Use X-Ray to find where in a multi-service call chain the time or errors accumulate
X-Ray records each request as a segment (the work one service did) and breaks that service's downstream calls into subsegments, then stitches all segments sharing one trace ID into a service map, the visual graph of services and the edges between them, color-coded for errors, faults, and throttles. Reach for it when end-to-end latency is high across microservices but no single component looks broken: the service map shows which hop accumulates the time, which a single service's logs cannot reveal.
Trap Reading one service's logs to explain high end-to-end latency across services: logs from a single hop cannot show where across the chain the time was spent.
- X-Ray default sampling traces the first request each second plus 5% of the rest
To control cost and overhead X-Ray does not trace every request: the default sampling rule records the first request each second (the reservoir) plus five percent of any additional requests that second. The consequence for root cause analysis is that a low-volume intermittent error may simply not have been sampled, so the absence of a trace is not proof the request succeeded. When you need fuller capture, raise the sampling rate or add a targeted sampling rule for the affected path.
Trap Concluding an intermittent request succeeded because no X-Ray trace exists for it, when default sampling captures only the first request each second plus 5% of the rest, so a missing trace may just mean it was not sampled.
- Use CloudTrail to find who called which AWS API, when, and from where
CloudTrail is the control-plane audit trail: it records management-event API activity, the principal who made the call, the API action, the timestamp, and the source IP. Reach for it when behavior changed without a deployment you initiated, or a call suddenly started being denied, for example a security group was edited or an IAM role's permissions changed. Logs, metrics, and traces observe your application, so none of them captures a control-plane change; CloudTrail is the only one of the four signals that answers "who or what changed it?".
Trap Hunting through CloudWatch Logs or X-Ray for the cause of an unexplained permission or config change, when those observe your application and only CloudTrail records who called the AWS API that changed it.
- CloudTrail is an API audit, not an application debug log
CloudTrail records that a principal called an API (say
ModifySecurityGroupRulesat 14:02 from a given IP) but it does not contain your function's internal log lines, error messages, or request payloads. For those you read CloudWatch Logs. Keep the boundary sharp: CloudTrail answers the "who changed the configuration" question only, and using it to debug application behavior will turn up nothing because it never sees inside your code.Trap Searching CloudTrail for an application's runtime error or request payload: it logs AWS API calls, not your code's internal events; read CloudWatch Logs for those.
- Triage a status code by side: 4xx blames the caller, 5xx blames the server
A 4xx status generally means the caller (your application or the client) sent a bad request (malformed input, missing auth, a 429 throttle), while a 5xx means the serving side faulted. This split tells you which direction to investigate first. On a multi-service path do not assume a 5xx is your code: narrow it by checking which hop reported the 5xx on the X-Ray service map, since the failing service may be a downstream dependency rather than your own.
Trap Assuming every 5xx on a multi-service path is your own service's fault, when the X-Ray service map may show the 5xx originated at a downstream dependency you call rather than in your code.
The disciplined RCA loop aligns timestamps across signals: when a metric spikes, note the exact window, then pull the X-Ray traces, the CloudWatch Logs lines, and any CloudTrail event inside that same window. A 5xx spike whose window lines up with a CloudTrail
ModifySecurityGroupRulesevent is a configuration regression, not a code bug, a conclusion no single signal could reach. Metrics localize the blast radius and bound the window; logs and traces then explain exactly what failed inside it.Trap Declaring a code bug from a 5xx spike alone, when correlating its time window against CloudTrail can reveal a
ModifySecurityGroupRulesevent that points at a configuration regression rather than your code.- Read an ECS task failure from stopCode and stoppedReason first, and treat exit code 137 as out-of-memory
When ECS tasks start then stop, run describe-tasks and read the stopCode (the category, such as ResourceInitializationError or EssentialContainerExited) and stoppedReason (the human-readable detail) before anything else. The most common container-level cause is a SIGKILL: a container exit code of 137 (128 + 9) means the OOM killer terminated it for exceeding its task-definition memory limit, so the fix is to raise the allocated memory, not to debug code. A ResourceInitializationError points instead at setup failing before the app ran (logging-driver or secrets connectivity).
Trap Reading container application logs to explain a 137 exit when there are none: the process was killed by the OS for exceeding its memory limit, which surfaces in stopCode/stoppedReason, not in app output.
4 questions test this
- A developer is troubleshooting an Amazon ECS service where tasks repeatedly stop shortly after starting. The developer uses the…
- A developer observes that an Amazon ECS service is failing to maintain its desired task count. Tasks start but quickly stop with an exit…
- A developer is troubleshooting an Amazon ECS Fargate service where containers are exiting unexpectedly. The developer examines a stopped…
- A developer is troubleshooting an Amazon ECS Fargate service where tasks are repeatedly stopping shortly after startup. The developer needs…
- A Fargate awslogs ResourceInitializationError is missing connectivity or task-execution-role permission, not bad code
Fargate tasks using the awslogs driver fail at startup with ResourceInitializationError / 'failed to initialize logging driver' for one of two reasons. First, connectivity: a task in a private subnet with no NAT gateway needs an interface VPC endpoint for CloudWatch Logs (com.amazonaws.region.logs), and that same private-subnet rule causes silently missing logs even when the task stays up. Second, permission: the task execution role must allow logs:CreateLogStream and logs:PutLogEvents, which the AmazonECSTaskExecutionRolePolicy managed policy grants. The identical 'unable to pull secrets or registry auth' failure needs the task's security group to allow outbound HTTPS (443) to Secrets Manager / ECR.
Trap Assuming a NAT gateway is enough on its own: the task's security group must still permit outbound 443 to reach CloudWatch Logs, Secrets Manager, or ECR endpoints.
6 questions test this
- A development team deployed an application on Amazon ECS using AWS Fargate. The tasks start but stop unexpectedly after a few seconds. The…
- A developer is running an Amazon ECS service on AWS Fargate and notices that container logs are not appearing in Amazon CloudWatch Logs.…
- A development team deploys an application to Amazon ECS on AWS Fargate. The team configures the task definition to use the awslogs log…
- A developer deploys an Amazon ECS service on AWS Fargate in a private subnet without internet access. The task definition uses the awslogs…
- A developer deployed an Amazon ECS service on AWS Fargate, but tasks are failing to start with a ResourceInitializationError. The stopped…
- A developer has configured an Amazon ECS Fargate task with the awslogs log driver to send container logs to Amazon CloudWatch Logs. The…
- Lambda emits two X-Ray segments: AWS::Lambda is the service, AWS::Lambda::Function is your code
Active tracing makes Lambda record two segments per invocation, so the X-Ray service map shows two nodes for one function. AWS::Lambda is the Lambda service overhead (scheduling, creating or unfreezing the execution environment, and downloading function code) and an error or latency here is a platform/init problem (including throttling), not your code. AWS::Lambda::Function is the handler running, so an error or high latency on that node is in your application logic. Decide which node shows the symptom before you touch anything.
Trap Debugging handler code because the function's X-Ray node shows latency, when the slow node is AWS::Lambda, which is service overhead like cold-start init or throttling rather than your application logic.
5 questions test this
- A developer is investigating a Lambda function failure using AWS X-Ray. The X-Ray trace shows two segments for the function - one with…
- A development team has deployed an AWS Lambda function that is invoked by Amazon API Gateway. The team has enabled active tracing on both…
- A company has deployed a microservices architecture using multiple AWS Lambda functions that call each other and external APIs. Users…
- A developer is troubleshooting performance issues in a serverless application that uses Amazon API Gateway and AWS Lambda. The developer…
- A company runs a serverless application with multiple Lambda functions integrated with API Gateway. Users report intermittent errors from…
- Create a field index to make Logs Insights lookups on a high-volume field fast and cheap
When Logs Insights queries that filter on a field such as requestId scan huge volumes and run slow and expensive, create a field index policy for that field (PutIndexPolicy / console) without changing the log format. Queries written as
filter requestId = 'value'(equality) then skip log events known not to contain the indexed value, cutting scan volume and cost. Across hundreds of log groups, thefilterIndexcommand restricts a query to only the groups indexed on that field.Trap Expecting a field index to speed up a non-equality filter such as a wildcard or range on requestId, when the index only lets an equality match skip events known not to contain the indexed value.
5 questions test this
- A developer is optimizing a Lambda function that processes high-volume transactions. The developer implements structured JSON logging with…
- A company has implemented structured JSON logging across their Lambda functions to improve debugging capabilities. A developer notices that…
- A development team manages a microservices application with multiple Lambda functions writing logs to CloudWatch Logs. They frequently…
- A company runs Lambda functions that process financial transactions. Developers need to debug performance issues across 500 log groups…
- A company has a high-volume microservices application generating terabytes of logs daily across multiple CloudWatch Logs log groups.…
- Build Logs Insights trend queries with stats and bin, and match timeouts on 'Task timed out'
To turn logs into a time series, use stats with aggregations grouped by bin(5m) (for example
stats count(*) by endpoint, bin(5m)); bin() creates the time buckets a chart needs. Filter HTTP errors by numeric range (filter status>=400 and status<=499for 4XX). Lambda timeouts do NOT log as ERROR (they emit a 'Task timed out' message) so capturing all failures needs a pattern likefilter @message like /ERROR/ or @message like /Task timed out/.Trap Filtering only on /ERROR/ to count all Lambda failures, when a timeout emits a 'Task timed out' message rather than ERROR, so it slips past that filter unless you match it explicitly.
6 questions test this
- A developer is troubleshooting API Gateway REST API errors and needs to find all 4XX client errors from the past hour. The developer has…
- A developer is debugging a production issue where some API requests are failing intermittently. The application uses structured JSON…
- A developer needs to create a CloudWatch Logs Insights query to analyze API Gateway access logs and identify latency trends. The query…
- A company's API Gateway REST API is experiencing high 4XXError rates according to CloudWatch metrics. The development team suspects that…
- A developer is troubleshooting intermittent failures in an AWS Lambda function that processes batch data. Some invocations are failing but…
- A developer is troubleshooting intermittent timeout errors in an AWS Lambda function that processes orders from an Amazon SQS queue. The…
- Use VPC Reachability Analyzer to find the blocking component without sending traffic
VPC Reachability Analyzer performs static configuration analysis between a source and destination (it sends no packets) making it the tool to proactively prove a path or pinpoint what blocks it (security group, network ACL, or route table) before any traffic flows. It reports the blocking component with explanation codes. Because it snapshots configuration at analysis time, after you change a rule you must run a NEW analysis; re-reading the old result still shows the stale, pre-change state.
Trap Expecting an existing Reachability Analyzer result to update after you fix a security group: it is a point-in-time snapshot, so you must analyze the path again.
6 questions test this
- A development team is using VPC Reachability Analyzer to troubleshoot why an Amazon EC2 instance in a private subnet cannot connect to a…
- A development team deployed a web application on Amazon EC2 instances behind an Application Load Balancer. After updating security group…
- A developer is troubleshooting connectivity issues between two Amazon EC2 instances in the same VPC. The developer has enabled VPC Flow…
- A developer needs to verify that a web application running on an Amazon EC2 instance is reachable from the internet through an Application…
- A developer runs VPC Reachability Analyzer to test connectivity from an internet gateway to an EC2 instance on port 443. The analysis shows…
- A developer's application running on EC2 instances cannot connect to an Amazon RDS database in a private subnet. The developer needs to…
- A VPC Flow Log REJECT means a security group or NACL denied the traffic
An action=REJECT record means a security group or network ACL blocked the traffic; check the security group first since it is evaluated first and is the most common cause. Because NACLs are stateless, return traffic is evaluated independently and needs explicit ephemeral-port rules. This is why one direction can show ACCEPT while the reply shows REJECT, or why an SG that allows a port still fails when the subnet's NACL does not. Flow logs only appear once there is real traffic on the interface (the log group is created on first traffic), and custom formats can add fields like instance-id, subnet-id, flow-direction, and tcp-flags.
Trap Blaming the security group for a REJECT on return traffic when the outbound request showed ACCEPT, when NACLs are stateless, so the reply needs its own explicit ephemeral-port rule that the SG, being stateful, does not require.
6 questions test this
- A developer is analyzing VPC Flow Logs published to Amazon S3 to understand traffic patterns for an EC2 instance. The developer needs to…
- A developer created a VPC Flow Log for an EC2 instance to troubleshoot connectivity issues. The flow log shows status as Active in the…
- A developer is troubleshooting why an EC2 instance in a public subnet cannot be accessed via SSH from the internet. The instance has a…
- A developer is analyzing VPC Flow Logs to troubleshoot intermittent connectivity issues between an Amazon EC2 instance and an on-premises…
- A developer is troubleshooting an issue where an Amazon EC2 instance in a private subnet cannot connect to an Amazon RDS database in…
- A developer is troubleshooting an application that fails to connect to an external service endpoint from an EC2 instance in a private…
- API Gateway logging needs an account CloudWatch role, and some client errors are never logged
Before any API Gateway logs appear, the account must have an IAM role (trusting apigateway.amazonaws.com, with AmazonAPIGatewayPushToCloudWatchLogs) configured in API Gateway Settings; without it, requests succeed but produce no logs. Even with logging on, API Gateway does not write certain client errors to execution logs (such as 403 from a wrong resource path, and excessive 429 or 413 errors), so enable custom access logging to capture them. To surface integration failures behind 500 errors, add $context.integrationErrorMessage to the access log format.
Trap Assuming execution logging captures every failed request, then concluding a missing 403 means the call never reached API Gateway, when certain client errors like a wrong-path 403 are absent from execution logs unless you turn on custom access logging.
4 questions test this
- A developer is setting up CloudWatch monitoring for an Amazon API Gateway REST API but notices that no logs appear in CloudWatch Logs after…
- A developer is investigating intermittent 500 Internal Server Error responses from a REST API in Amazon API Gateway that uses a Lambda…
- A developer is troubleshooting 403 errors returned to clients from an Amazon API Gateway REST API. The CloudWatch execution logs for the…
- A developer notices that their Amazon API Gateway HTTP API is not generating CloudWatch metrics or logs for some failed requests. The…
- Read RDS ReplicaLag carefully: -1 means replication is broken, and an undersized replica lags
A ReplicaLag value of -1 does not mean zero lag: it means replication is not active or the lag can't be determined (for MySQL/MariaDB, equivalent to Seconds_Behind_Master = NULL), so check the replication state and event log for errors. Sustained positive lag often comes from a read replica with a smaller instance class than the primary: a replica replays the primary's full write load and must match or exceed its compute/storage to keep up. For consistent reads, the app can check ReplicaLag and route time-sensitive queries only to replicas below an acceptable threshold.
Trap Reading a ReplicaLag of -1 as zero lag and a perfectly healthy replica, when the value actually signals replication is not active or cannot be measured, so the replica may be receiving nothing.
4 questions test this
- A developer is troubleshooting performance issues with an Amazon RDS for MySQL read replica. The application reports stale data when…
- A developer manages an Amazon RDS for MySQL database that is experiencing slow response times during peak hours. CloudWatch metrics show…
- A company runs an Amazon RDS for MySQL database with multiple read replicas to handle read-heavy workloads. The development team notices…
- A developer manages an Amazon RDS for MySQL database with three read replicas in the same AWS Region. The application sends read traffic to…
Code Observability
Read full chapterUnlock with Premium — includes all practice exams and the complete study guide.
Application Optimization
Read full chapterUnlock with Premium — includes all practice exams and the complete study guide.