DVA-C02Chapter 73 of 101Objective 3.2

SAM Local Testing and Debugging

This chapter covers AWS SAM local testing and debugging—a critical skill for serverless developers and a key topic in the DVA-C02 exam (Domain: Deployment, Objective 3.2). You will learn how to run and test AWS Lambda functions and API Gateway endpoints locally using the SAM CLI, debug applications with step-through debugging, and integrate with AWS services like DynamoDB Local. Approximately 5-8% of exam questions touch on SAM local testing, focusing on CLI commands, configuration, and common debugging workflows. Mastering this topic will save you hours of deployment cycles and help you pass the exam.

25 min read
Intermediate
Updated May 31, 2026

SAM Local Testing as a Movie Set Rehearsal

Imagine you're a film director planning a complex scene with actors, props, and special effects. Instead of filming on location with the full crew and expensive equipment, you run a rehearsal on a soundstage. The soundstage has simplified versions of key elements: a mock-up of the set, stand-in actors, and a script supervisor who simulates the director's cues. During rehearsal, you can test the scene's flow, adjust lighting, and practice camera movements without incurring the cost of a full shoot. If something goes wrong, you pause, fix it, and restart instantly. The rehearsal environment mirrors the final location shoot closely enough that you can confidently direct the actual filming. Similarly, AWS SAM local testing lets you run a serverless application on your local machine using Docker containers that emulate AWS Lambda, API Gateway, and DynamoDB. You invoke functions locally with simulated events, test API endpoints via a local HTTP server, and debug with breakpoints—all without deploying to AWS. This local rehearsal catches errors early, saves deployment time, and ensures your application runs correctly when you finally deploy to the cloud for production.

How It Actually Works

What is SAM Local Testing and Why Does It Exist?

AWS Serverless Application Model (SAM) is an open-source framework for building serverless applications. SAM local testing extends the sam build and sam deploy workflow by allowing you to run your serverless application locally before deploying to AWS. This is essential for rapid development and debugging because deploying to the cloud for every code change is slow and costly. With SAM local, you can invoke Lambda functions locally, simulate API Gateway requests, and even interact with local versions of AWS services like DynamoDB and S3.

The DVA-C02 exam tests your ability to use SAM CLI commands (sam local invoke, sam local start-api, sam local start-lambda) and understand how they work under the hood. You must also know how to configure environment variables, mount local files, and use debugging tools like AWS SAM CLI with IDEs.

How SAM Local Works Internally

SAM local uses Docker containers to emulate the AWS Lambda execution environment. When you run sam local invoke, the SAM CLI: 1. Reads the SAM template (template.yaml) to understand your application's resources. 2. Builds a Docker image that mimics the Lambda runtime (e.g., Python 3.9, Node.js 18). 3. Mounts your function code into the container. 4. Passes the event payload (from a file or stdin) as the invocation event. 5. Captures the function's response, logs, and any errors.

For sam local start-api, the CLI starts a local HTTP server that emulates API Gateway. It parses the SAM template's API event sources and routes incoming HTTP requests to the appropriate Lambda function. The server runs on http://127.0.0.1:3000 by default (configurable with -p).

Key components: - Docker: Required for running Lambda containers. SAM CLI uses Docker images from public.ecr.aws/lambda/. - samconfig.toml: Optional configuration file for default parameters. - events/: Directory where you can store JSON event files to simulate various AWS event sources (e.g., API Gateway, S3, SQS).

Key Commands and Their Options

- sam local invoke [FunctionName] [options] - -e, --event <file>: Path to a JSON event file. - -n, --env-vars <file>: Path to a JSON file containing environment variables. - -l, --log-file <file>: Write logs to a file. - -d, --docker-network <network>: Connect to a specific Docker network. - --profile <profile>: AWS credentials profile. - --region <region>: AWS region. - --container-host <host>: Host for the container (default: localhost). - --container-host-interface <interface>: Interface for the container host. - --debug: Print debug logs.

- sam local start-api [options] - -p, --port <port>: Port to listen on (default: 3000). - -l, --log-file <file>: Write logs to a file. - --profile, --region, --debug: Same as above. - --warm-containers <type>: Strategy for keeping containers warm (EAGER, LAZY). - --container-host, --container-host-interface: Same. - --env-vars, --docker-network: Same.

sam local start-lambda [options]: Similar to start-api but exposes a Lambda Invoke API endpoint.

Environment Variables and Secrets

SAM local does not automatically inherit AWS credentials or environment variables from your shell. You must explicitly provide them via: - --env-vars flag pointing to a JSON file like:

{
  "MyFunction": {
    "TABLE_NAME": "my-table",
    "BUCKET_NAME": "my-bucket"
  }
}

Or by setting environment variables in the container using --container-env-vars (newer versions).

For AWS credentials, SAM local uses the same credential chain as the AWS CLI: environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN), shared credential file (~/.aws/credentials), or IAM roles (if running on EC2). However, note that local invocations do not have IAM permissions; any calls to AWS services from your function will fail unless you provide valid credentials that have the necessary permissions.

Debugging with SAM Local

SAM local supports step-through debugging using the AWS SAM CLI debug mode. To debug: 1. Start your function with sam local invoke -d 5858 MyFunction (or any port). 2. Attach a debugger (e.g., in VS Code, use a launch configuration that attaches to localhost:5858). 3. Set breakpoints in your code. 4. Invoke the function; execution will pause at breakpoints.

For Python, you need to install debugpy in your container or use the AWS Lambda runtime image that includes it. For Node.js, the runtime includes the inspector.

Limitations of SAM Local

No IAM enforcement: Local invocations do not enforce IAM policies. Your function can call any AWS service if credentials are provided, even if the real Lambda would be denied.

Limited service emulation: Only Lambda, API Gateway, and DynamoDB Local are natively supported. For other services like SQS, SNS, or Step Functions, you must use local emulators or mock them.

No cold start simulation: Local containers start instantly; the 100ms cold start latency is not emulated.

No event mapping: SQS, S3, and DynamoDB Streams event sources are not triggered automatically. You must manually invoke the function with a sample event.

Performance: Local execution may differ from AWS Lambda's actual hardware and memory limits.

Interacting with DynamoDB Local

SAM local integrates with DynamoDB Local, an in-memory database that emulates DynamoDB. To use it:

Start DynamoDB Local as a Docker container: docker run -p 8000:8000 amazon/dynamodb-local

In your SAM template, configure the function's environment variable DYNAMODB_ENDPOINT to http://localhost:8000.

When running locally, your function will use the local DynamoDB instead of the real one.

Example: Testing an API Locally

Given a SAM template with an API Gateway event source:

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs18.x
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

To test locally: 1. Build: sam build 2. Start API: sam local start-api 3. Send request: curl http://127.0.0.1:3000/hello

The SAM CLI will invoke the HelloWorldFunction and return the response.

Using sam local invoke with Event Files

To test with specific events (e.g., an S3 put event):

sam local invoke ProcessS3Event -e events/s3-put.json

Where events/s3-put.json contains:

{
  "Records": [
    {
      "eventSource": "aws:s3",
      "s3": {
        "bucket": {
          "name": "my-bucket"
        },
        "object": {
          "key": "my-key"
        }
      }
    }
  ]
}

SAM Local and Layers

If your function uses Lambda layers, SAM local automatically downloads and mounts them if the layer is defined in the same template or is an AWS-provided layer. For custom layers stored in S3, you must have the layer locally available or reference it by ARN (SAM CLI will attempt to download it).

Configuration Files

samconfig.toml: Automatically created by sam deploy --guided. Can be used to store default parameters for local commands.

env.json: Common file name for environment variables (though any name works).

Walk-Through

1

Install Prerequisites

Before using SAM local, ensure Docker is installed and running on your machine. Install the AWS SAM CLI via pip (`pip install aws-sam-cli`), brew, or the MSI installer for Windows. Verify installation with `sam --version`. Also install the AWS CLI and configure credentials with `aws configure`. Docker is essential because SAM local runs Lambda functions inside containers that mimic the AWS runtime. Without Docker, `sam local invoke` will fail with an error about missing Docker.

2

Initialize and Build the Application

Create a SAM application using `sam init` (optional) or use an existing SAM template. Run `sam build` to compile your code and prepare dependencies. This command processes the template, installs dependencies (e.g., pip installs for Python), and creates a `.aws-sam/build` directory with the deployment artifacts. If you skip `sam build`, `sam local invoke` will use the raw source code, which may miss dependencies.

3

Invoke a Function Locally

Use `sam local invoke FunctionName` to invoke a single Lambda function. Optionally provide an event file with `-e events/event.json`. The SAM CLI pulls the appropriate Lambda runtime Docker image (e.g., public.ecr.aws/lambda/python:3.9), mounts your built code, and passes the event. The function executes, and you see stdout, stderr, and the response. If you omit the function name and only have one function, SAM invokes it automatically.

4

Start a Local API Gateway Emulator

Run `sam local start-api` to start a local HTTP server that emulates API Gateway. The server listens on port 3000 by default. It reads the SAM template and creates routes for all API event sources. When you send an HTTP request to the appropriate path, SAM invokes the corresponding Lambda function and returns the response. You can test with curl, Postman, or a web browser. The server logs each request and response.

5

Debug with Breakpoints

To debug your function, start it with `sam local invoke -d 5858 FunctionName`. This enables the debug port 5858. Then, in your IDE (e.g., VS Code), create a launch configuration that attaches to `localhost:5858`. Set breakpoints in your code and invoke the function. Execution will pause at breakpoints, allowing you to inspect variables and step through code. For Node.js, use the inspector protocol; for Python, ensure `debugpy` is installed in the container.

6

Use Environment Variables and Secrets

Create a JSON file (e.g., `env.json`) with environment variables for each function. Pass it with `-n env.json`. Example: `{"MyFunction": {"TABLE_NAME": "test-table"}}`. For AWS credentials, the SAM CLI uses your default AWS profile or environment variables. If your function calls AWS services, ensure the credentials have the necessary permissions. You can also use `--profile` to specify a different profile.

7

Integrate with DynamoDB Local

For functions that use DynamoDB, start DynamoDB Local: `docker run -p 8000:8000 amazon/dynamodb-local`. Set the environment variable `DYNAMODB_ENDPOINT` to `http://host.docker.internal:8000` (or `localhost` if running natively). Then, when you invoke the function locally, it will interact with the local DynamoDB instance. Create tables and seed data using the AWS CLI with `--endpoint-url http://localhost:8000`.

What This Looks Like on the Job

Enterprise Scenario 1: CI/CD Pipeline with Local Testing

A fintech company develops a serverless application for processing loan applications. The application consists of multiple Lambda functions triggered by API Gateway, S3 events, and Step Functions. The team integrates SAM local testing into their CI/CD pipeline (e.g., Jenkins or GitLab CI). For every pull request, the pipeline runs sam build and sam local invoke with predefined event files to validate function logic. They also run sam local start-api and use a test suite (e.g., pytest with requests) to hit the local API endpoints. This catches integration bugs early, such as incorrect event parsing or missing environment variables. The pipeline uses Docker containers with the SAM CLI pre-installed and mounts the workspace. They use a local DynamoDB container for database tests. This approach reduces deployment failures by 40% and speeds up developer feedback loops.

Enterprise Scenario 2: Debugging a Production Bug

A travel booking platform encounters an issue where a Lambda function fails intermittently when processing high-volume SQS messages. The developer replicates the SQS event structure using a sample event file from CloudWatch Logs. They run sam local invoke ProcessBooking -e events/sqs-event.json and attach a debugger to step through the code. They discover a race condition caused by a global variable not being reset between invocations. Without SAM local, debugging would require multiple deployments with added logging, taking hours. With local debugging, they fix the bug in 20 minutes. They also use sam local start-lambda to simulate the Lambda Invoke API for testing inter-function calls.

Enterprise Scenario 3: Onboarding New Developers

A large e-commerce company onboards new developers to a serverless microservices architecture. Instead of granting full AWS access, they provide a local development environment using SAM local. New hires clone the repository, run sam build and sam local start-api, and begin testing their changes immediately. They use a shared local DynamoDB container with anonymized production data. This eliminates the risk of accidental deployments or costly mistakes. The company also uses sam local invoke with a library of event files that simulate various scenarios (e.g., order placed, payment failed). Developers can run these tests without internet access. This practice reduces the learning curve and ensures code quality before the first deployment.

How DVA-C02 Actually Tests This

Exactly What DVA-C02 Tests on SAM Local

The DVA-C02 exam covers SAM local under Domain 3: Deployment, Objective 3.2: Deploy serverless applications using the AWS Serverless Application Model (SAM). Questions focus on: - Commands: sam local invoke, sam local start-api, sam local start-lambda, and their options. - Prerequisites: Docker must be installed and running. - Event simulation: Using -e flag with JSON event files. - Environment variables: Using -n flag with env JSON file. - Debugging: Using -d flag to enable debug port. - Limitations: What SAM local cannot emulate (IAM, cold starts, event mappings).

Common Wrong Answers and Why

1.

"SAM local invoke automatically uses the AWS credentials from the function's IAM role." - Wrong. Local invocations do not have IAM roles. You must provide credentials via environment variables or the AWS CLI profile.

2.

"You must deploy the application to AWS before testing locally." - Wrong. SAM local is specifically for testing before deployment.

3.

"sam local start-api requires an internet connection." - Wrong. It runs entirely locally; only the Docker image pull requires internet.

4.

"SAM local can emulate all AWS services." - Wrong. Only Lambda, API Gateway, and DynamoDB Local are natively supported. Other services require external emulators.

Specific Numbers and Terms

Default port for start-api: 3000.

Debug port: typically 5858 or 5859.

Docker images: public.ecr.aws/lambda/<runtime>.

Event file format: JSON with structure matching the AWS event source.

sam build must be run before local invoke to include dependencies.

Edge Cases and Exceptions

If your template uses intrinsic functions like !Ref or !Sub, SAM local resolves them using mock values (e.g., MyTable for a DynamoDB table name). You can override with environment variables.

Layers defined in the same template are automatically mounted. External layers (from S3) require the layer to be accessible locally or by ARN (SAM CLI will attempt to download).

For functions that use AWS SDK calls, you must provide valid AWS credentials with appropriate permissions, or the calls will fail with authorization errors.

How to Eliminate Wrong Answers

When you see a question about SAM local testing, remember:

If the answer mentions "deploy to AWS first" or "requires internet", it's likely wrong.

If it says "automatically uses IAM role", it's wrong.

If it says "emulates all services", it's wrong.

Look for keywords: Docker, environment variables file, event file, debug port, sam build.

Key Takeaways

Docker must be installed and running for SAM local commands to work.

Run `sam build` before `sam local invoke` to include dependencies.

Use `-e events/event.json` to simulate AWS event sources.

Use `-n env.json` to provide environment variables.

Use `-d 5858` to enable debugging and attach an IDE.

SAM local does not enforce IAM policies; provide credentials via AWS CLI profile.

Only Lambda, API Gateway, and DynamoDB Local are emulated natively.

The default port for `sam local start-api` is 3000.

SAM local cannot simulate cold starts or Lambda execution limits.

Event mappings (S3, SQS, etc.) are not triggered automatically.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

sam local invoke

Invokes a single Lambda function and returns the response.

Requires an event file or stdin for the invocation payload.

Good for unit testing individual functions.

Supports debug mode with -d flag.

Does not start an HTTP server.

sam local start-api

Starts a local HTTP server that emulates API Gateway.

Routes HTTP requests to Lambda functions based on the SAM template.

Good for integration testing APIs.

Supports debug mode per function (if enabled).

Listens on port 3000 by default.

Watch Out for These

Mistake

SAM local testing requires an active internet connection to invoke functions.

Correct

No. After pulling the Docker images, SAM local runs entirely offline. The function code executes locally; only the initial Docker pull requires internet.

Mistake

sam local invoke automatically uses the IAM role defined in the SAM template.

Correct

No. IAM roles are not enforced locally. The function uses the AWS credentials from your local environment (e.g., ~/.aws/credentials). You must provide credentials if the function calls AWS services.

Mistake

SAM local can emulate all AWS services, including SQS, SNS, and Step Functions.

Correct

No. Only Lambda, API Gateway, and DynamoDB Local are natively supported. Other services require external emulators or mocking.

Mistake

You must run sam deploy before using sam local invoke.

Correct

No. sam local invoke is designed for local testing before deployment. You only need sam build to prepare the code.

Mistake

SAM local perfectly replicates the production Lambda environment, including cold starts and memory limits.

Correct

No. Cold starts are not simulated, and memory/CPU may differ from actual AWS Lambda. Performance testing should be done on AWS.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

Do I need Docker to use SAM local invoke?

Yes, Docker is required. SAM local runs Lambda functions inside Docker containers that mimic the AWS Lambda runtime. If Docker is not installed or running, you will get an error. You can install Docker Desktop (Windows/Mac) or Docker Engine (Linux) and ensure the daemon is running.

How do I pass environment variables to a Lambda function in SAM local?

Create a JSON file with the function name as the key and environment variables as a map. For example: `{"MyFunction": {"TABLE_NAME": "my-table"}}`. Then use `-n env.json` with `sam local invoke` or `sam local start-api`. You can also pass them via the `--env-vars` option.

Can I use SAM local to test functions that call other AWS services?

Yes, but you must provide AWS credentials that have permission to call those services. SAM local uses your local AWS credentials (from environment variables or ~/.aws/credentials). The function will make real API calls to AWS, so be cautious with production services. Alternatively, use local emulators like DynamoDB Local.

How do I debug a Lambda function running locally with SAM?

Use the `-d` flag to specify a debug port, e.g., `sam local invoke -d 5858 MyFunction`. Then attach a debugger from your IDE (e.g., VS Code) to localhost:5858. For Python, ensure `debugpy` is available; for Node.js, the inspector is built in. Set breakpoints in your code and invoke the function.

What is the difference between sam local invoke and sam local start-api?

`sam local invoke` runs a single Lambda function once and returns the result. It is ideal for unit testing. `sam local start-api` starts a local HTTP server that emulates API Gateway, listening for HTTP requests and routing them to the appropriate Lambda function based on your SAM template. It is used for integration testing of APIs.

Can I use SAM local to test functions triggered by S3 or SQS events?

Yes, but you must manually provide a sample event file that mimics the S3 or SQS event structure. SAM local does not automatically trigger functions from event sources. For example, download an S3 event from CloudTrail and save it as a JSON file, then use `sam local invoke -e s3-event.json`.

How do I test a function that uses DynamoDB locally?

Start DynamoDB Local as a Docker container: `docker run -p 8000:8000 amazon/dynamodb-local`. Set the environment variable `DYNAMODB_ENDPOINT` to `http://host.docker.internal:8000` (or `localhost` on Linux). Then invoke your function normally. You can create tables and seed data using the AWS CLI with `--endpoint-url http://localhost:8000`.

Terms Worth Knowing

Ready to put this to the test?

You've just covered SAM Local Testing and Debugging — now see how well it sticks with free DVA-C02 practice questions. Full explanations included, no account needed.

Done with this chapter?