Skip to main content

Be a Problem Solver

Configuring AWS Lambda Deployment via AWS SAM

Table of Contents

AWS Lambda, a serverless computing service provided by AWS, executes code in response to events and automatically manages the compute resources required by that code. AWS SAM (Serverless Application Model) is an open-source framework for building serverless applications and provides a simplified way of defining the AWS services needed by your serverless application. This post explores configuring AWS Lambda deployment using an AWS SAM configuration file

# Prerequisites

  1. AWS credentials configuration: Ensure that your local machine is configured with AWS credentials. If you haven’t already, you can follow the step-by-step instructions provided in the official documentation.

  2. AWS SAM CLI: Make sure you have the AWS SAM CLI installed on your local machine. You can easily do so by following the instructions outlined in the official documentation.

  3. Docker Desktop: You need to have Docker Desktop installed on your local machine. If you haven’t done so, you can follow the instructions in the official documentation.

# Create a new AWS Lambda project from template

To begin, you can use the sam init command to initialize a new AWS Lambda project. You can choose from the available templates offered by AWS or opt for a custom template. For instance, the following command initializes a new AWS Lambda project using a template I created and hosted on GitHub.

mkdir my-lambda-project && cd my-lambda-project # Create a new directory and navigate to it
sam init --location gh:slchangtw/lambda_template_example # Use --location option to specify the location of the template

The custom template can locate online or locally. Here are examples for both cases https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-init.html#using-sam-cli-init-examples. Note that if the template is located on GitHub, it must be in the first level of the repository.

# Code of the Lambda function

Before deploying the Lambda function, let’s examine its code. Start by navigating to the src directory of the newly created project. There, you’ll find a file named app.py, which contains the Lambda function’s code. This function makes a request to The Cat API and returns the URL of a random cat image. Don’t forget to include any necessary third-party libraries in the requirements.txt file located in the directory to ensure they’re available for use within the Lambda function.

import requests


def lambda_handler(event, context):
    try:
        # Making a request to The Cat API
        response = requests.get("https://api.thecatapi.com/v1/images/search")

        # Checking if request was successful
        if response.status_code == 200:
            data = response.json()
            image_url = data[0]["url"]
            return {"statusCode": 200, "body": image_url}
        else:
            return {
                "statusCode": response.status_code,
                "body": f"Failed to fetch cat image: {response.text}",
            }
    except Exception as e:
        return {"statusCode": 500, "body": f"An error occurred: {str(e)}"}

# Lambda template configuration

The template.yaml file, situated in the project’s root directory, holds the configuration utilized by AWS CloudFormation, a service used to establish Lambda functions. This file, formatted in YAML, contains the following sections:

# A
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Get Cat Image API

# B
Globals:
  Function:
    Timeout: 3
    MemorySize: 128

Resources:
  # C
  LambdaExecRoles:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"

  # D 
  GetCatImageFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: app.lambda_handler
      Runtime: python3.10

Let’s go through the sections of the template.yaml file:

## A. AWSTemplateFormatVersion and Transform

The AWSTemplateFormatVersion field specifies the capabilities of the template. The Transform field specifies the macro that AWS CloudFormation uses to process the template.

## B. Globals

This section holds the default settings applied to all functions within the template. In this instance, we configure the Timeout and MemorySize parameters.

## C. Resources

This section contains the resources that will be created by AWS CloudFormation. In this case, we define an IAM role to allow the execution of the Lambda function.

## D. Function definition

The GetCatImageFunction resource sets up the Lambda function. The CodeUri indicates where the function’s code is stored. Handler specifies the starting function Lambda will use. Runtime sets the environment for the function.

# SAM configuration file

A simple deployment flow consists of three steps:

  1. build: prepares the deployment,
  2. package: creates a zip file and uploading it to S3,
  3. deploy: deploys the package to AWS.

If you refer to the documentation, you’ll discover that each step offers various flags and parameters you can specify. For instance, using sam build --use-container will construct the Lambda function within a Docker container.

“When dealing with numerous parameters and flags, it’s easy to overlook some or mix up the command. This is where the SAM configuration file comes to the rescue. By storing a set of flags for each command, you can streamline the process. Simply replace the dash in the flags with an underscore and store them in the samconfig.toml file. The basic syntax of the file is as follows

version = 0.1
[environment]
[environment.command]
[environment.command.parameters]
flag = parameter value

Here is an example of the samconfig.toml file for different commands and their parameters:

version = 0.1

[default]
[default.global.parameters]
s3_bucket = "aws-lambda-deployment-test"
s3_prefix = "get-cat-image"

[default.build.parameters]
cached = true
parallel = true
use_container = true
skip_pull_image = true

[default.package.parameters]
output_template_file = "packaged.yaml"

[default.deploy.parameters]
stack_name = "get-cat-image"
capabilities = "CAPABILITY_IAM"
template_file = "packaged.yaml"
confirm_changeset = true

The samconfig.toml file defaults to using the environment name default. In upcoming posts, we’ll define distinct sets of flags for various environments like testing and production. From AWS SAM CLI command reference, you can find the meaning of each flag and parameter for every command.

One important point to highlight is the stack_name parameter in the deploy command. This name must be unique within the region where you’re deploying the Lambda function. Otherwise, you would mess up the deployments of other Lambda functions.

# Deploy the Lambda function

With all flags and parameters stored in the samconfig.toml file, you can deploy the Lambda function using the following commands:

sam build && sam package && sam deploy

Press y to confirm the changeset when prompted. Once the deployment is finished, you’ll find your Lambda function listed in the AWS Lambda console. You can test the function by clicking the in the Test tab.

Imgur Imgur

# Clean up

To clean up the resources created by the deployment, you can use the following command:

sam delete

# Summary

  1. Custom templates can be utilized to create a new AWS Lambda project.
  2. The template.yaml file contains the configuration used by AWS CloudFormation to set up the Lambda function.
  3. The samconfig.toml file stores a set of flags for each SAM command, removing the need to specify them every time you run the command. Importantly, you can consistently deploy different Lambda functions using the same command sam build && sam package && sam deploy, as the flags are stored in the configuration file.

# Learn more