Elevating Your Serverless Development with AWS SAM
Tags: aws, sam, iac, terraform
Published: 2023-01-22 17:34:33

IAC is essential for modern day development as it allows for more efficient and effective management of infrastructure. It helps to automate the provisioning and deployment of resources, and enables software engineers to manage their infrastructure as code in a version control system. This allows for better collaboration and tracking of changes, making it easier to rollback or update resources as needed.

I've been working on Terraform for a bit now, but never had a chance to explore much about SAM which can easily let you deploy AWS serverless resources using CloudFormation. So I thought of picking up on AWS SAM and explore why it is so good. So in this blog, I tried giving some context about AWS SAM and why it is useful and also sharing one sample use-case which I tried recently.

**AWS Serverless Application Model** a.k.a AWS SAM is an open-source tool that allows software engineers to define their serverless infrastructure as code, making it easy to manage, test, and deploy their applications. It also comes with a CLI which can be used to deploy & manage serverless applications on AWS.

One of the main benefits of using SAM is that it simplifies the process of creating and deploying serverless applications. With SAM, we can use a simple YAML or JSON template to define the resources that their application needs, such as Lambda functions, API Gateway, and DynamoDB tables. SAM then takes care of creating and deploying these resources to AWS, making the process much easier and more efficient than doing it manually.

Another benefit of using SAM is that it provides a consistent development experience across different languages and frameworks. SAM supports multiple languages, including Python, Node.js, and Go, and it can be used with different frameworks, such as Flask, Express, and Django. This means that we can use the same template and CLI commands to deploy the applications, regardless of the language.

To get started with SAM, we need to install the SAM CLI on the local machine. The SAM CLI can be installed using the pip package manager by running the following command:

```sh
pip install aws-sam-cli
```

Once the SAM CLI is installed, we can use it to create a new application template by running the following command:

```sh
sam init --runtime <runtime>
```

Where <runtime> is the language and version that the application will be written in, such as nodejs12.x or python3.8. This command will create a new directory with a basic template that includes a Lambda function and an API Gateway.

To deploy the application to AWS, we can use the sam deploy command. This command will create or update the resources defined in the template, and it will also create an S3 bucket to store the application's artifacts. To deploy the application, we need to run the following command:

```sh
sam deploy --stack-name <stack-name> --capabilities CAPABILITY_IAM
```

Where `<stack-name>` is the name of the CloudFormation stack that will be created. The `--capabilities CAPABILITY_IAM` flag is required to create IAM resources, such as roles and policies, that are defined in the template.

Let's do a small demo now!

Below is an example of using SAM to deploy a simple Python application on AWS. The application consists of a Lambda function that handles a GET request to an API Gateway endpoint, which retrieves data from a DynamoDB table. Above commands while explaining SAM were just for reference, to build the demo please start using commands from here on -

First, we will create a new directory for our application and initialize it with the SAM CLI:

```sh
sam init --runtime python3.8
```

After running above command, it will ask you some questions, please choose `1` to select `AWS Quick Start Templates` and then subsequently choose `1` to select `Hello World Example` and when you are asked for app name, type it as `demo-app-sam`.

This will create a new directory with the basic template files, including `template.yaml` and `hello_world` directory.

Next, we will create a new directory `demo` and create a new file called `app.py` this file will contain our Lambda function code:

```sh
mkdir demo
touch demo/app.py
```

Then in our `app.py` file, we will import the necessary modules like `json`, including `boto3` to interact with `DynamoDB`, and write a function named `handler` that will handle the GET request to the API Gateway endpoint, and retrieve data from the DynamoDB table:

```python
import json
import boto3

def handler(event, context):
    dynamodb = boto3.resource("dynamodb")
    table = dynamodb.Table("demo-table")

    response = table.scan()
    return {
        "statusCode": 200,
        "body": json.dumps(response["Items"]),
        "headers": {
            'Content-Type': 'application/json',
        }
    }
```

Now we will update our template.yaml to include the resources needed for our application.

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  demo-app-sam

  Sample SAM Template for demo-app-sam

Globals:
  Function:
    Timeout: 3
    MemorySize: 128
    Tracing: Active
  Api:
    TracingEnabled: true

Resources:
  DemoFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: demo/
      Handler: app.handler
      Runtime: python3.8
      Policies:
      - DynamoDBCrudPolicy:
          TableName: demo-table
      Architectures:
      - x86_64
      Events:
        DemoApi:
          Type: Api
          Properties:
            Path: /
            Method: get
  DemoTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: demo-table
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1
```

This template defines a Lambda function named DemoFunction that is triggered by a GET request to the `/`endpoint of an API Gateway. It also defines a DynamoDB table named `demo_table` with a single id field.

Finally, to deploy our application, we will run the following command:

```sh
sam deploy --stack-name demo-app-sam --capabilities CAPABILITY_IAM --guided
```

This will create or update the resources defined in the template, including the Lambda function, API Gateway, and DynamoDB table. Once the deployment is complete, we can test our application by sending a GET request to the API Gateway endpoint, which should return data from the DynamoDB table.

In this example, we have demonstrated how to use SAM to deploy a Python application on AWS, which consist of a Lambda function that handles a GET request to an API Gateway endpoint, retrieves data from a DynamoDB table, and returns it to the client. 

Now to summarize, AWS SAM is a powerful tool for building and deploying serverless applications on AWS. It provides a simple and consistent way to define serverless infrastructure as code, making it easy to manage, test, and deploy applications. The SAM CLI also provides a convenient way to create and deploy applications to AWS, making the process much more efficient and streamlined. With the help of examples and code, we can easily understand the process and start building their own serverless applications on AWS.

Feel free to reach out to [me](https://linktr.ee/inovizz) if you have any questions, I'd be happy to chat.

P.S. - Once you are done running and testing your demo, don't forget to delete the created resources from AWS ;)

Use below command to do that -

```sh
sam delete --stack-name demo-app-sam
```