AWS SAM CLI: Local Development Tips

published on 11 November 2024

AWS SAM CLI supercharges your serverless app development. Here's why it's a game-changer:

  • Test Lambda functions locally without cloud deployment
  • Debug step-by-step in your IDE
  • Deploy faster with sam build and sam deploy
  • Mimic Lambda environment on your machine using Docker
  • Run integration tests locally with sam local start-lambda

Key tips for AWS SAM CLI mastery:

  1. Use sam local invoke for single function testing
  2. Fire up a local API Gateway with sam local start-api
  3. Speed up development with sam sync --stack-name <your-stack> --watch
  4. Optimize Docker usage to reduce container startup times
  5. Validate templates with sam validate --lint

Remember: While local testing is crucial, always do final tests in AWS before going live.

Setup Requirements

Let's get you set up with AWS SAM CLI for local development. Here's what you need:

Install AWS SAM CLI

AWS SAM CLI

First, make sure you have:

  1. An AWS account
  2. AWS CLI installed
  3. Docker installed
  4. Python installed (optional, but useful)

Now, let's install AWS SAM CLI:

  • macOS: Download the .pkg file for your processor from AWS. Run it and follow the prompts.
  • Windows: Grab the 64-bit MSI installer from AWS. Install it, then open a new command prompt and run:
    sam --version
    
  • Linux: It depends on your distro. For Amazon Linux 2:
    sudo amazon-linux-extras install docker
    sudo service docker start
    sudo usermod -a -G docker ec2-user
    
    Then follow AWS's Linux install guide for SAM CLI.

After installing, check everything's working:

aws --version
sam --version
docker --version

If you see version numbers, you're all set!

Set Up AWS Credentials

Now, let's get your AWS credentials sorted:

  1. Create an IAM user in AWS with the right permissions
  2. Get an access key ID and secret access key for this user
  3. In your terminal, run:
    aws configure
    
  4. Enter your access key ID, secret access key, default region, and output format

This creates a credentials file in your home folder's .aws directory.

"AWS CLI stores your settings in a default profile in the credentials file." - AWS Docs

Local Testing Basics

AWS SAM CLI makes testing Lambda functions on your machine a piece of cake. Let's jump into the key parts of local testing with SAM.

Run Functions with sam local invoke

Want to run Lambda functions locally? The sam local invoke command is your best friend. Here's how to use it:

  1. Go to your project's root directory in the terminal.
  2. Type: sam local invoke <FunctionName>

Let's say you have a function called "HelloWorldFunction". You'd run:

sam local invoke HelloWorldFunction

This builds your function in a local Docker container and runs it. You'll see the function's output in stdout and logs in stderr.

Want to test with a specific event? No problem. Use the --event option:

sam local invoke --event events/s3.json S3JsonLoggerFunction

This shows you how your function would handle a real S3 event in AWS.

Set Up template.yaml Files

Your template.yaml file is the heart of your SAM app. It's where you define your Lambda functions and their settings. Here's a simple example:

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

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ./
      Handler: app.lambda_handler
      Runtime: python3.8

This template sets up a basic Python Lambda function. CodeUri points to your code, Handler is the entry point, and Runtime is the execution environment.

Make sure your template.yaml is in the project root or a .aws-sam subfolder. That's where SAM CLI looks for it.

Testing API Gateway-triggered functions? Add an Events section like this:

Events:
  ApiEvent:
    Type: Api
    Properties:
      Path: /hello
      Method: get

Now you can use sam local start-api to fire up a local API Gateway for testing.

Local testing is great for quick checks, but it's not the whole story. Always do final tests in the AWS cloud before you go live.

Debug Your Code

Let's dive into debugging AWS Lambda functions locally. With AWS SAM CLI, you can catch bugs before they hit the cloud. Here's how to set up debugging and add useful logs.

Connect Your IDE Debugger

VSCode is a go-to for debugging AWS SAM apps. Here's the setup:

  1. Get the AWS Toolkit for VSCode
  2. Make sure Docker's on your machine
  3. In your .vscode folder, create a launch.json file:
{
  "version": "0.2.0",
  "configurations": [{
    "name": "Attach to SAM CLI",
    "type": "node",
    "request": "attach",
    "address": "localhost",
    "port": 5858,
    "localRoot": "${workspaceRoot}/",
    "remoteRoot": "/var/task",
    "protocol": "inspector",
    "stopOnEntry": false,
    "sourceMaps": true
  }]
}

Ready to debug? Here's what to do:

  1. Drop some breakpoints in your code
  2. Fire up your function with SAM CLI in debug mode:
sam local invoke -e ./events/event.json -d 5858
  1. Hit F5 in VSCode to latch onto the running function

Now you're set to step through your code, peek at variables, and squash bugs like a pro.

Add Useful Logs

Good logging is your best friend when hunting down Lambda function issues. Here's how to make the most of AWS SAM CLI's logging:

Sprinkle console.log() statements throughout your code to spit out key info. Then, use sam logs to see what's going on:

sam logs -n HelloWorldFunction --stack-name mystack

This grabs logs for HelloWorldFunction in the mystack stack.

Want to watch logs in real-time? Tack on --tail:

sam logs -n HelloWorldFunction --stack-name mystack --tail

Need to zero in on errors? Filter your logs:

sam logs -n HelloWorldFunction --stack-name mystack --filter "error"

You can even snag logs from a specific time window:

sam logs -n HelloWorldFunction --stack-name mystack -s '10min ago' -e '2min ago'

AWS SAM CLI's got your back - it highlights timeout messages in red and prettifies JSON log messages. Makes parsing those logs a breeze.

sbb-itb-6210c22

Daily Development Tips

Want to supercharge your AWS SAM CLI workflow? Here's how:

Watch Mode: Your New Best Friend

Sick of manual deployments? SAM CLI's watch mode has your back. It's like having a personal assistant that updates your code in the cloud every time you hit save.

Here's how to turn it on:

sam sync --stack-name <your-stack-name> --watch

Got a stack named "blog"? Just run:

sam sync --stack-name blog --watch

Now SAM CLI's got its eyes on your project files. Change your Lambda function code, and BOOM - it's in AWS. No more context switching. No more waiting. Just code, save, and test.

And here's a cool trick: sam sync is smart. It knows the difference between tweaking your code and overhauling your infrastructure. So it'll update your Lambda function without rebuilding everything else. Time = saved.

Taming Your Dependencies

Let's face it: messy dependencies can turn your serverless project into a nightmare. Here's how to keep things clean:

1. Dependency managers are your friends

Use npm for Node.js or pip for Python. They're like bouncers for your project, making sure only the right versions get in.

2. Lambda Layers: Share the love

Got libraries that multiple functions use? Lambda Layers are your answer. They'll slim down your deployment package and make updates a breeze.

3. Size matters

Use tools like webpack or rollup to shrink your dependencies. Smaller packages mean faster deployments and quicker cold starts. Win-win.

4. Version control is key

Always commit your package.json or requirements.txt. It's like a recipe for your project - everyone needs to use the same ingredients.

5. Stack smart

Look at how your functions depend on each other. Can you reuse packages? It'll make your life easier down the road.

Here's what a solid package.json might look like for a Node.js project:

{
  "name": "my-sam-project",
  "version": "1.0.0",
  "dependencies": {
    "aws-sdk": "^2.1001.0",
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "aws-sam-webpack-plugin": "^0.7.0",
    "webpack": "^5.65.0"
  }
}

Speed Up Development

AWS SAM CLI is great, but it can slow down as your projects grow. Let's look at some ways to make your local development faster.

Reuse Containers

Creating and cleaning up Docker containers can eat up a lot of time. Here's how to fix that:

1. Skip pulling images

Add this flag when starting your local API:

sam local start-api --skip-pull-image

It's a simple change, but it works wonders. One developer said it cut their request times to under a second.

2. Use Docker's layer caching

Docker builds images in layers and can reuse unchanged ones. To make the most of this:

  • Put stable stuff at the top of your Dockerfile
  • Group related commands into single RUN instructions
  • Use multi-stage builds to separate build and runtime environments

Reduce Build Times

Faster builds mean a smoother workflow. Try these:

1. Make your Dockerfile better

A good Dockerfile can make a big difference. Here's an example:

# Base layer
FROM node:14 AS base
WORKDIR /app
COPY package*.json ./
RUN npm install

# Build stage
FROM base AS build
COPY . .
RUN npm run build

# Production stage
FROM node:14-alpine
COPY --from=build /app/dist /app
CMD ["node", "/app/index.js"]

This setup separates dependencies, building, and runtime. The result? A smaller, faster final image.

2. Try SAM Accelerate

SAM Accelerate is a game-changer. It's way faster than the old CloudFormation way for single function changes. Use this command to sync your local changes to AWS:

sam sync --stack-name mystack --watch

3. Use caching

Turn on SAM CLI caching:

sam build --cached

This reuses built layers, saving you time.

4. Windows tweaks

If you're on Windows:

  • Make a .dockerignore file to skip unnecessary files
  • Give Docker Desktop more memory and CPU in its settings
  • Run SAM CLI commands in WSL2 for better speed

These tips should help speed up your AWS SAM development. Remember, faster builds mean more time for coding!

Fix Common Problems

Let's tackle some common AWS SAM CLI issues head-on. We'll focus on Docker problems and template errors.

Fix Docker Issues

Docker

Docker powers AWS SAM CLI's local testing. Here are some typical Docker hiccups and how to solve them:

1. "Running AWS SAM projects locally requires Docker" error

This means Docker's missing or not running. Here's the fix:

  • Download and install Docker from their website
  • Fire up the Docker daemon
  • Check it's working by typing docker --version in your terminal

2. Slow container startup

Speed things up with these tricks:

  • Use --skip-pull-image when starting your local API:
    sam local start-api --skip-pull-image
    
    This can slash request times to under a second.
  • Optimize your Dockerfile to use Docker's layer caching:
    FROM node:14 AS base
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    
    FROM base AS build
    COPY . .
    RUN npm run build
    
    FROM node:14-alpine
    COPY --from=build /app/dist /app
    CMD ["node", "/app/index.js"]
    
    This multi-stage build separates dependencies, building, and runtime. Result? A smaller, faster image.

3. "Failed to create managed resources: Unable to locate credentials" error

AWS credentials aren't set up right. Here's how to fix it:

  • Run aws configure in your terminal
  • Enter your AWS access key ID, secret access key, region, and output format
  • Test with a simple AWS CLI command like aws s3 ls

Fix Template Errors

AWS SAM templates are your serverless app's blueprint. Here's how to squash common template bugs:

1. Template validation errors

Use sam validate to spot template errors:

sam validate --lint

This uses cfn-lint to check your template, giving you detailed error messages and suggestions.

2. "Can't find exact resource information with given stack name" error

This often pops up when using sam remote invoke without --stack-name. To fix:

  • Always include the --stack-name option
  • If it persists, try the function's logical ID instead of its ARN
  • Check your samconfig.toml for conflicting stack names

3. API Gateway endpoint resolution issues

If you're seeing "curl: (6) Could not resolve: endpointdomain (Domain name not found)" when invoking your API Gateway endpoint, try these:

  • Check if your app deployed successfully in the AWS CloudFormation console or AWS CLI
  • Double-check your curl command for typos in the URL
  • Make sure your API Gateway stage deployed correctly

Summary

AWS SAM CLI is a game-changer for serverless app development. It brings AWS to your computer, making it easier to build, test, and deploy Lambda functions.

Here's why AWS SAM CLI rocks for local development:

1. Local Testing

Test Lambda functions on your machine without cloud deployment. It's faster and easier to fix bugs. Use sam local invoke for single functions or sam local start-api for a local API Gateway.

2. Easy Debugging

Debug your code step-by-step in your favorite IDE. SAM CLI's debug mode works great with tools like VS Code, helping you squash bugs before they hit production.

3. Quick Deployments

sam build packages your code and dependencies, while sam deploy pushes your app to AWS. This cuts down deployment times big time.

4. Matching Environments

SAM CLI uses Docker to mimic the Lambda environment on your machine. This means what works locally should work in the cloud, reducing those "but it worked on my machine" moments.

5. Automated Testing

Use sam local start-lambda to run integration tests against a local Lambda-like endpoint. Test thoroughly without racking up cloud costs.

But remember: local testing is great, but it's not everything. Always do final tests in AWS before going live.

"Local step-through debugging tightens the feedback loop by making it possible for you to find and troubleshoot issues that you might run into in the cloud." - AWS Documentation

To get the most out of AWS SAM CLI:

  • Run sam build after changing your code to update the .aws-sam directory.
  • Use --use-container with sam build to compile functions in a Docker container that matches Lambda.
  • Try sam sync --stack-name <your-stack-name> --watch for real-time updates while you work.

FAQs

What Python versions are supported by AWS SAM?

AWS SAM CLI runs on Python 3.7 and 3.8. But don't mix this up with the Python versions you can use for your Lambda functions.

Jeff Gebhart, Sr. Specialist TAM for Serverless at AWS, puts it simply:

"AWS SAM CLI is mainly written in Python 3 and we support Python 3.7 and 3.8."

Here's the cool part: You can still use newer Python versions in your Lambda functions. Want to use Python 3.11? Just set Runtime: python3.11 in your SAM template. Python 3.12? Same deal: Runtime: python3.12.

But here's a pro tip: Use a Python virtual environment for your AWS SAM projects. It's like giving your project its own sandbox to play in, away from other Python stuff on your computer.

Oh, and heads up: AWS has a preview Lambda container base image for Python 3.11. Sounds exciting, right? Just remember:

  • It might change
  • It's not ready for prime time (production) yet

So, while AWS SAM CLI sticks with 3.7 and 3.8, you've got options for your actual Lambda functions. Just pick the right tool for the job!

Related posts

Read more