AWS SAM can be used to test and debug your serverless applications locally. This is great for testing to be sure that all of your code is working before you deploy it to the cloud. Who does not love not having syntax or logic surprises when you run your code after deploying it to the cloud, right?
First things first, before we deep dive into the step-by-step guide below, let’s make sure we have all the prerequisites met.
1. Install SAM. In this example, I am using version 1.39.
2. Install CDK. In this example, I am using version 2. If you already have it installed, check the version. Recommendation is to upgrade it to version 2.
3. Install Docker. This is needed as SAM will run the Lambda functions locally in a container so we can get a similar runtime environment as we do on AWS Lambda.
Step-by-step instructions to create and test Lambda function locally
Step 1: Creating a project directory
You can run the command below in an empty directory to generate a project.
cdk init app –language python
Above command creates a project directory in this case called CDK_LAMBDA_LOCAL, containing some extra files such as readme and instructions which has some useful commands to help setup the virtual environment.
Step 2: Activating virtual environment.
Run the command below to set up a virtual environment for all the python dependencies. So it basically runs an “activate” script that’s in the virtual environment bin directory. You can also find basic commands in instructions file in the directory.
$ source .venv/bin/activate
Step 3: Install dependencies.
We will be installing just two basic libraries here, aws-cdk-lib and constructs.
We do not need to install all the Lambda specific dependencies… benefit of using CDK version 2.
Make sure to include these two in requirements.txt file. Open up the terminal and run the command below to install them.
python -m pip install -r requirements.txt
Step 4: Define Sample Lambda function.
When you run init command in Step 1, it auto-generates a directory containing necessary files such as app.py which gives you information about basic parameters of your CDK stack. It should have also generated a home directory, go to the python function in that directory.
In this case, editing cdk_lambda_local_stack.py. By default, it comes with some boilerplate here. I got rid of some other dependencies here that we don’t need and imported Lambda related dependency aws_lambda as you can see in line 3 image below.
Defining a Lambda function with following parameters passed – reference to self, name of the function, python runtime, directory in which the Lambda code is located and handler entrypoint.
Name of my Lambda function is DemoHandler. I am using Python 3.8 as runtime and the code is located in the lambda directory. My handler entrypoint is handler.handle, where handler is a file within that lambda directory and handle is a function defined in that file. See the example of my lambda function below:
Step 5: Creating Sample Lambda Function.
Now let’s create a Lambda function as mentioned above (lambda directory with file named handler containing function handle).
First, I am going to create my lambda directory. You can create it using file explorer or just run cmd command mkdir lambda in terminal.
Next, add a file named handler in the lambda directory created above. Again, you can create this using file explorer or by running cmd command touch handler.py in terminal.
Once we have our lambda handler file, let’s add a function called handle. Just using basic signature for Lambda function with parameter event and context. Adding a few print statements, printing event (one of the parameters passed to the function) and a text “Hello, World!”.
If you have a Lambda function ready to test, skip this part.
Step 6: Generate CloudFormation template.
In the terminal, run the below command to generate a CloudFormation template file for all our code. This acts as a specifications file which allows AWS to know what you want to create in the cloud.
Note: Make sure you are in the root directory when running this command.
Let’s take a look at the directory cdk.out that got generated using the command above. In that directory, you will find a SAM template. Mine is named CdkLambdaLocalStack.template.json. You can find the Lambda function we created in the above steps in the template, with random code suffixed to the name. It contains all the extra specifications we provided while creating the function (such as handler name, python version, etc.) and metadata field with asset path.
If you look at the file structure, you will see the folder named the same as the value of asset path in metadata. The reference to our Lambda function handler is located here. This will be used by SAM to invoke our Lambda function.
Step 7: Invoke Lambda function locally using SAM without a test event.
Run the command below to invoke Lambda function locally.
sam local invoke -t <path_to_sam_template_file>
Since we are not passing any event in the command above, printing the event line prints nothing but you should see Hello, World! in the output.
If you run into errors, check these two below:
- To make sure you have SAM is set up correctly, just run sam command in terminal.
- Check if the docker was installed correctly.
You can also interact with other AWS dependencies (such as DynamoDB call, S3 call, etc.) depending on the role configured in your AWS CLI.
Step 8: Create a sample event locally for testing Lambda function.
You can use Lambda functions with so many different types of events like an AWS S3 event, SNS event, SQS event, etc.
If you do not have an event to test, you can use SAM to generate different types of sample events. If you have a test event ready, skip this step below.
In this example, I will be passing a SNS event. Follow the steps below to generate one:
1. Create events directory. You can simply create it using file explorer or run cmd command mkdir events.
2. Run the below command to generate a SNS event.
sam local generate-event sns notification
3. Copy the output of this command. It is in JSON format. Now, let’s save it to a file.
4. Create a file under events directory. You can simply create it using file explorer or run cmd command touch sns_event.json.
5. Paste the output content copied above in the new file and save.
Step 9: Invoke Lambda function locally using SAM with a test event.
Run the command below to invoke Lambda function locally with a test event passed to it.
sam local invoke -t <path_to_sam_template_file> -e <path_to_test_event_file>
Now since we passed the test event to the invoke command, you will see that the event value passed gets printed in the output along with Hello, World!
You can use SAM and CDK to run your Lambda functions locally. You can also test the Lambda function with various types of events or different types of inputs, which can also be generated locally using SAM. Again, I cannot emphasize on this more but this is great for unit testing/debugging your code before you push it to the cloud.