Serverless - Create, debug and deploy Lambda and API Gateway via AWS SAM and AWS Cloud9
Tags: aws, cloud, serverless, cloud9
Published: 2021-01-20 20:14:59

Let’s say you want to create and deploy a very basic serverless architecture - an API backend that consists of an Amazon API Gateway endpoint and an AWS Lambda function.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sroqd8rpvnlzxfkxzcqx.png)

For that you need to provision the following resources:
:point_right: API Gateway
:point_right: Lambda function
:point_right: IAM role

What is the fastest and the most convenient way to provision and deploy these serverless resources using AWS native framework? 

## **AWS Serverless Application Model**

And the answer is AWS SAM. 

**AWS SAM (Serverless Application Model)** is meant to build *serverless* applications. Built on AWS CloudFormation, AWS SAM provides *shorthand syntax* to declare serverless resources. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3ysntxksjt3aoqo1u1y6.png)

These 20 lines of code turn into the following serverless architecture:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5z76snf46hagwntaheb9.png)

I took these screenshots from Eric Johnson’s awesome [tech talk](https://www.youtube.com/watch?v=JCqpS2RuayM&ab_channel=AWSOnlineTechTalks) 
which I would highly recommend to watch.

During deployment, AWS SAM transforms the serverless resources into CloudFormation syntax, enabling you to build serverless applications faster.

With that being said, let’s get our hands dirty!


##  **Step 1. Set up AWS Cloud9 environment**

In order to write, run, and debug applications with just a browser, without needing to install or maintain a local IDE, we’ll go with **AWS Cloud9** IDE. It preconfigures the development environment with all the SDKs, libraries, and plug-ins needed for serverless development. It also provides an **AWS Toolkit** extension for locally testing and debugging AWS Lambda functions and API Gateway.

First step is to set up a new AWS Cloud9 environment. Sign in to `AWS Management Console`, go to `AWS Cloud9` and click on `Create environment`:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bwvywbliqz8n0u98nokx.png)

Give a name to your new environment (you can optionally add description) and go to the next step:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/tg247ndtlosf4uljwu3f.png)

I’ve selected *t2.micro* instance type as it is covered by the AWS Free Tier. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/90a8odjpgsi20tzp2whg.png)

Once you are done with environment configurations, review your settings and submit. It should take a couple of minutes to launch a new EC2 instance for a new Cloud9 environment. As you can check, there are a lot of preinstalled runtimes and package managers, such as Docker, AWS CLI, pip:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l4ity0gbha35hid3vfye.png)

You can run the following command to get a list of all available packages (it’s a pretty long list!):

```YAML
yum list installed
```

## **Step 2. Create a SAM application**

On the upper left hand side of the screen you should see AWS Toolkit's `AWS` icon. Click on it to open `AWS:Explorer` window. Expand your region and right-click on `Lambda`, then `Create new SAM Application`:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5bc3c46n1mfxmaboqtxj.png)

Cloud9 should walk you through the following steps:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zcx1e5ly4uk746lnfffu.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qw0u1r9vuc97jyadgvnf.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9bjfqh147a3ursrjkp6f.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wf0z14uqb1cs6gs5wswb.png)

Voila! AWS SAM creates a directory with the name that you provided as the project name with all necessary files and folders:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ahyygmr98ef64fr6k77f.png)

- **hello_world** - code for the application's Lambda function
- **events** - invocation events that you can use to invoke the function
- **tests** - unit tests for the application code 
- **template.yaml** - a template that defines the application's AWS resources



##  **Step 3. Debug your function locally**

Navigate to `hello_world/app.py` to see AWS Lambda handler logic. We can make a little clean up and uncomment *location*:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/k56zantohd5qpk1yoa6w.png)

Use **Ctrl + S** button to save changes in `app.py` file.

Make sure that you've specified *requests* dependency in `requirements.txt` (if you use Node.js functions then check `package.json`):

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cbf5qqsldlfwtt74mxn2.png)

Let’s leverage AWS Toolkit to make debugging easier! AWS Toolkit is a very powerful tool that will invoke SAM CLI to build the serverless project, deploy the code to a local Docker instance, invoke the Lambda in Docker, allowing you to step-through your Lambda code. To run the function AWS Toolkit needs launch configuration file. It should be auto-generated during a new SAM app creation - check `launch.json` file under the `.c9` folder.

By the way, if you don't see `.c9` folder and some other folders/files then you might need to turn on `Show Hidden Files`:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/eiojrj20q2p3d30zu3cv.png)

Ok, back to launch configuration that gives us more flexibility to configure launchers for our SAM template. As it was mentioned before,  `launch.json` file can be found under the `.c9` folder. You can also open the file by `Editing Launch Configurations`:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/98ttk2bybebe15zfw594.png)

In case you are missing `launch.json` file or if it is empty, open your template file, and click on `Add Debug Configuration` link. It should automatically set launch configurations for you.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9zioviifoowx3ustdghx.png)

Once launch configuration file is set you should see your function in debugging dropdown:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9l3tlz5hb15eaj28ttn3.png)

Set some breakpoints in source code (`hello_world/app.py`), then select `MyFirstSamApp:HelloWorldFunction` option from dropdown and click on `Run`:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/e0so6hm0d6l0raicfxrf.png)

Note, in case AWS Toolkit fails to run the function, throwing `RuntimeError: Container does not exist`, you would need to increase the size of your EBS volume. See how to fix the issue [here](https://dev.to/tiamatt/troubleshooting-aws-cloud9-runtimeerror-container-does-not-exist-1oap).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/solhxyvcxreu8ehhyoqk.png)

Step-through debugging makes it easier to understand what the code is doing. Thanks to AWS Toolkits it's easy to set breakpoints, execute code line by line, and inspect the values of variables:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qw3tpbebnx2u8nlbawwx.png)

After debugging you should get the final response in AWS Toolkit window:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qec28j85r30beewthoap.png)


##  **Step 4. Build the project**

Building your serverless application involves taking your AWS SAM template file, application code, and any applicable language-specific files and dependencies, and placing all build artifacts in the proper format and location for subsquent steps in your workflow.

First, change into the project directory, where the `template.yaml` file for the sample application is located.

```YAML
cd MyFirstSamApp
```

Then build the project inside a Docker container:

```YAML
sam build --use-container
```

AWS SAM builds any dependencies that your application has, and copies your application source code to folders under `.aws-sam/build` to be zipped and uploaded to Lambda.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bwwfz2uxywy6cs298ust.png)

##  **Step 5. Deploy the project to the AWS Cloud**

After you develop and build your serverless application, you can deploy your application using the following AWS SAM command:

```YAML
sam deploy --guided
```
When you specify the `--guided` flag, the AWS SAM zips your application artifacts, uploads them to Amazon S3, and then deploys your application to the AWS Cloud.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ohe6qtfaki3gp9d9m1dq.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/n32l794ndaya5ltas2vl.png)

AWS SAM deploys the application using AWS CloudFormation. In the output you can see the changes being made to your AWS CloudFormation stack.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/g388hz4fmdl7bij11yo1.png)

After you've created an AWS CloudFormation stack, you can use the `AWS Management Console` to view its data and resources:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/pvxcnj1c2m1pxro51yrc.png)

## **Results**

Time to call our API Gateway endpoint! Go to `Outputs` sections and click on the link for `HelloWorldApi`:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4jsbjki1nadwzx0jpjjv.png)

When you send a GET request to the API Gateway endpoint, the Lambda function is invoked. This function should return a *hello world* message with the public IP address:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xgymrfhw3zz120hxzf2z.png)

So, we successfully invoke the function and got the expected response with status code 200.

Now, you know how to configure and use AWS SAM and Cloud9 to build the serverless applications for AWS. Congratulations!

## **Clean Up**

You might be charged for running resources. That is why it is important to clean all provisioned resources once you are done with the stack. Use the AWS CloudFormation command to delete the stack along with all the resources it created:

```YAML
aws cloudformation delete-stack --stack-name my-first-sam-apps-stack
```


## **Summary**

Using AWS SAM for serverless application development saves a lot of time by eliminating much of the boilerplate that AWS CloudFormation templates require. It extends AWS CloudFormation with new resource types that follow AWS best practices and are more comfortable to use.