How to run a lambda locally and deploy it to AWS using SAM
Tags: aws, sam, python, serverless
Published: 2020-04-12 19:19:01

This article was also published on [razcodes.dev](https://razcodes.dev "razcodes.dev")

[AWS SAM](https://aws.amazon.com/serverless/sam/ "AWS SAM") or Serverless Application Model, is a framework for building serverless applications. There are several things I like about this framework that I have just discovered, from the fact that it's an extension of CloudFormation which gives you an awesome reliable way to deploy and describe your application and resources to the fact that in combination with Docker it allows you to test and debug your code locally.

This article will serve as a quick intro to SAM to get you a taste of what the process might look like.

## Prerequisites

In my examples, I am using a mac, but you should be able to get the same experience using a different OS with minor changes here and there. To get started, you will need to have the following things in place.

[AWS Account](https://aws.amazon.com/free "AWS")

[AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html "AWS CLI")

```bash
❯ aws --version
aws-cli/2.0.0 Python/3.8.1 Darwin/19.4.0 botocore/2.0.0dev4
```

[Docker](https://docs.docker.com/get-docker/ "Docker") 

```bash
❯ docker --version
Docker version 19.03.8, build afacb8b
```

[SAM CLI](https://aws.amazon.com/serverless/sam/ "SAM CLI")

```bash
❯ sam --version
SAM CLI, version 0.47.0
```

[Python](https://www.python.org/ "Python")

```bash
❯ python3 --version
Python 3.8.1
```

## Getting started

First step is to create a new project in a folder of your choice using the _init_ option. For this example I will be using the Python runtime so I will pass that as a parameter to the SAM CLI.

```bash
sam init --runtime python3.8 --name sam-lambda-demo
```

```bash
Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Cloning app templates from https://github.com/awslabs/aws-sam-cli-app-templates.git

AWS quick start application templates:
        1 - Hello World Example
        2 - EventBridge Hello World
        3 - EventBridge App from scratch (100+ Event Schemas)
Template selection: 1

-----------------------
Generating application:
-----------------------
Name: sam-lambda-demo
Runtime: python3.8
Dependency Manager: pip
Application Template: hello-world
Output Directory: .

Next steps can be found in the README file at ./sam-lambda-demo/README.md
```

This will create all the folders and files that you would need for a simple _Hello World_ app. You can open the newly created folder in VS Code and explore the files and folders created.

```bash
cd sam-lambda-demo
code .
```

The two important files to look at right away would be **README.md**, that is a nicely documented file with more information about what is going on, and then **template.yaml**, which is the file that will be used to create the CloudFormation template and get things ready for deployment.

## Deploy to AWS

You will need an S3 bucket in your AWS account, where your code will be stored. Keep in mind that buckets name have to be unique so make sure to chose an _original_ name. I called mine **raz-sam-us-east-1**. You can create a new bucket from the console or to create a new bucket using the AWS CLI:

```bash
aws s3 mb s3://raz-sam-us-east-1
```

First you will need to create the package. This will create a new yaml file for CloudFormations as well as upload all the code to AWS in your S3 bucket.

```bash
sam package --template-file template.yaml --output-template-file deploy.yaml --s3-bucket raz-sam-us-east-1
```

Once that is done, you can run the deploy command that will create the stack in CloudFormations. You need to provide the command with the stack name of your choice as well as the deploy.yaml file that was created in the last step.

```bash
sam deploy --template-file deploy.yaml --stack-name SAMLambdaDemo --capabilities CAPABILITY_IAM
```

A nice screen will be presented to you in the terminal showing the progress of the stack creation. Once the process is complete you can look at the **Outputs** section on the screen for a link to the new API endpoint, name of the lambda function, as well as the role. Copy the URL for the api and put it in your browser to see the "hello world" message on your screen.

```bash
{"message": "hello world"}
```

You can also log into the AWS console and under **CloudFormations** -\> **Stacks** find your new stack. There you can go under _Resources_ to see everything that was built as well as under _Outputs_ where you can see the same info that was presented above in the terminal.

Once you are done playing around, if you want to delete the stack together with all the resources that have been created you can do it right from the console or from the CLI.

```bash
aws cloudformation delete-stack --stack-name SAMLambdaDemo
```

## Run it locally

Mare sure you have Docker up and running for this as it will spin up a new container.

There are two ways of doing this. You can run it as a function when you just expect the result in the terminal:

```bash
sam local invoke HelloWorldFunction --no-event
```

This will spin up a container, run the function and shut it down. Keep in mind that the first run will take longer because it will have to download the Python3.8 Docker image.

```bash
Invoking app.lambda_handler (python3.8)

Fetching lambci/lambda:python3.8 Docker container image......................................................................................................................................
Mounting /Users/raz/aws-sam/sam-lambda-demo/hello_world as /var/task:ro,delegated inside runtime container
START RequestId: cb2eff67-910e-15d1-7f6f-48087ac290bb Version: $LATEST
END RequestId: cb2eff67-910e-15d1-7f6f-48087ac290bb
REPORT RequestId: cb2eff67-910e-15d1-7f6f-48087ac290bb  Init Duration: 88.72 ms Duration: 2.58 ms       Billed Duration: 100 ms Memory Size: 128 MB     Max Memory Used: 25 MB

{"statusCode":200,"body":"{\"message\": \"hello world\"}"}
```

You can also run it in a way that will start a local web server, and you will be able to see the results in the browser.

```bash
sam local start-api
```

Once you do that, it will create a local web server and present you with a local URL that you can visit.

```bash
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-04-12 13:45:29  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
```

If you want to cleanup the Docker images you can first list them.

```bash
docker images
```

Then delete the one that was created, which in my case is _lambci/lambda:python3.8_.

```bash
docker rmi lambci/lambda:python3.7
```

## Conclusion

There are many interesting things you can do using AWS SAM and this was just a short intro, so go out there and explore.