Developing AWS lambda functions + S3 Resources Locally with LocalStack: A Hello World

Rodrigo Brayner
4 min readDec 16, 2021

--

Photo by C Dustin on Unsplash

Saving computational costs is a widely discussed topic in IT organizations and on the Internet, with the clear objective of finding solutions to get the job done, with quality, spending as little as possible. And, at C.E.S.A.R, it is no different. We adopted multiple public clouds for different projects, with AWS being one of them. The developers and testers create many resources on a daily basis, of different AWS services, which increase (a lot) our billing costs, monthly 💰. To reduce it, we've decided to use the LocalStack to allow our teams to develop locally (offline), with a local cloud stack, similar as they would be developing directly in AWS. Below is a description of what LocalStack is capable of, copied from their official website:

LocalStack provides an easy-to-use test/mocking framework for developing Cloud applications. It spins up a testing environment on your local machine that provides the same functionality and APIs as the real AWS cloud environment.

In this article, I'm going to introduce a very simple example of creating a nodejs lambda function that puts a file (object) into an S3 bucket and writes some content to it, all performed locally by using the LocalStack. I've created a repository with the full code, which I recommend you to download before beginning the reading, since we are going to make use of it.

Requirements

First of all, you should have installed the following softwares:

Also, if you have no AWS credentials configure, please configure with the command below, by using fake credentials (i.e., by type anything):

aws configure

Also, as already mentioned, clone the repository:

git clone git@github.com:rbrayner/localstack-samples.gitcd localstack-samples

All the commands present on this article were tested against the following operating systems:

  • MacOS Monterey ARM64 (M1)
  • Ubuntu 20.04

Run LocalStack

To run the LocalStack, we are going to use docker and docker-compose. To get it up and running, execute the following command inside the cloned repository folder:

docker-compose up -d

Verify if the container is running. The STATUS should be UP:

docker ps -a

To check how the service is created, please refer to the docker-compose.yml file present within the repository.

Create an S3 bucket

To create an S3 bucket, run the following command:

aws --endpoint-url=http://127.0.0.1:4566 s3api create-bucket --bucket mybucket --no-cli-pager

If you do not wish to use the —-endpoint-url option everytime, you can use awslocal instead.

To list the recently created bucket, execute:

aws --endpoint-url=http://127.0.0.1:4566 s3 ls

Create the lambda function

Now, let's create the nodejs lambda function. The code is shown below, which basically puts an object (file.txt), with some content, into an S3 bucket named mybucket. Within the repository, the file is named index.tpl.

The lambda function

First of all, edit the .env file and change the HOST_IP_ADDRESS variable value. You should change to a local IP bound to one of your computer's interface (e.g., 192.168.0.10). You can search for an IP by running the following commands: ifconfig or ip a. Please, do not use 127.0.0.1.

Then, after this initial configuration is done, you can export the variable by running:

set -asource .env

Next, replace any variables present on index.tpl, with the envsubst command:

envsubst < index.tpl > index.js

Now, it's time to create the the lambda function, by running the following commands:

zip lambda.zip index.jsaws --endpoint-url=http://127.0.0.1:4566 lambda create-function --function-name=example --runtime="nodejs12.x" --role=fakerole --handler=index.handler --zip-file fileb://lambda.zip --no-cli-pager

Invoke the lambda function

Finally, after the lambda has been created, with the name example, you can invoke it with the following command:

aws --endpoint-url=http://127.0.0.1:4566 lambda invoke --function-name example out --log-type Tail --query 'LogResult' --output text |  base64 -d

As you can see in the figure above, an object file.txt was created, by invoking the lambda, inside mybucket.

List the created S3 object

To verify that the object was actually created, execute the below listing command:

aws --endpoint-url=http://127.0.0.1:4566 s3 ls s3://mybucket

You can also download the create file and check its contents:

aws --endpoint-url=http://127.0.0.1:4566 s3 cp s3://mybucket/file.txt file.txtcat file.txt

Nice! Our S3 object was successfully created by our lambda function!

Photo by Matthieu Joannon on Unsplash

Run in single command

I've developed a Makefile to simplify the whole process. In a nutshell, you can run all the commands above, including the deploy of LocalStack via docker, by following the steps below:

  1. Configure the .env file as already described, changing the IP address.
  2. Then, run:
make example-01

Destroy

To destroy all the created resources, as well as the LocalStack itself, just run:

make destroy

--

--