Some time ago, I tried LocalStack for serverless architecture locally (I'm always looking for ways to work with serverless locally: Link), and it left me with a very good impression. Now, I’ve seen that they’ve expanded their features and the services they integrate, so I’ve taken on the task of exploring it in depth. In this post, I’ll share my thoughts and a step-by-step guide to Getting Started.
What is LocalStack?
It is a tool that allows you to locally test some AWS services, but in the words of LocalStack :
Develop and test your AWS applications locally to reduce development time and increase product velocity. Reduce unnecessary AWS spend and remove the complexity and risk of maintaining AWS dev accounts.
Previously, I have written about how to test Lambda and some services locally, but LocalStack offers us some additional alternatives in its free version and extra functionalities in the paid license version.
Install LocalStack
We log in to the LocalStack account; I am personally logged in with my GitHub account. LocalStack offers several authentication methods.
On Linux, download the file:
curl --output localstack-cli-3.7.0-linux-amd64-onefile.tar.gz \
--location https://github.com/localstack/localstack-cli/releases/download/v3.7.0/localstack-cli-3.7.0-linux-amd64-onefile.tar.gz
We extract and install:
sudo tar xvzf localstack-cli-3.7.0-linux-*-onefile.tar.gz -C /usr/local/bin
We check which version we have installed:
localstack --version
# 3.7.0
Configure the Auth token:
Go to the LocalStack page after logging in: https://app.localstack.cloud/workspace/auth-token
Copy the
Auth
Token
- Export the Auth token on the machine or configure it with the LocalStack command
localstack auth set-token XXX-XXX-XXX
# Token configured successfully
Start LocalStack
We run the start command
localstack start
If we run the command directly, the following error will appear:
[11:14:59] starting LocalStack in Docker mode 🐳 localstack.py:503
2024-09-03T11:15:00.313 INFO --- [ MainThread] localstack.utils.bootstrap : Execution of "prepare_host" took 764.13ms
❌ Error:
===============================================
License activation failed! 🔑❌
Reason: Unexpected license server error: {"error": true, "message": "licensing.license.not_assigned"}
Due to this error, Localstack has quit. LocalStack pro features can only be used with a valid license.
- Please check that your credentials are set up correctly and that you have an active license.
You can find your credentials in our webapp at https://app.localstack.cloud.
- If you want to continue using LocalStack without pro features you can set `ACTIVATE_PRO=0`.
We set the ACTIVATE_PRO=0 parameter as commented in the last line:
export ACTIVATE_PRO=0
We restart the service:
localstack start
The service should start correctly:
__ _______ __ __
/ / ____ _________ _/ / ___// /_____ ______/ /__
/ / / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/
/ /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,<
/_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_|
💻 LocalStack CLI 3.7.0
👤 Profile: default
[11:16:12] starting LocalStack in Docker mode 🐳 localstack.py:503
container image not found on host bootstrap.py:1272
[11:17:02] download complete bootstrap.py:1276
──────────────── LocalStack Runtime Log (press CTRL-C to quit) ─────────────────
LocalStack version: 3.7.2.dev6
LocalStack build date: 2024-09-03
LocalStack build git hash: daa45717
Ready.
We set up a test environment:
We follow the getting started guide to test with a known stack. In future posts, we will test our own stacks. The guide we will follow is:
https://docs.localstack.cloud/getting-started/quickstart/
Download the source code, which is a reference architecture that enables image resizing to an S3 Bucket and other functionalities:"
git clone https://github.com/localstack-samples/sample-serverless-image-resizer-s3-lambda.git cd sample-serverless-image-resizer-s3-lambda
We install the project dependencies:
It is recommended to install Python version 3.9 as indicated in the getting started guide, because the test Lambdas will not work correctly otherwise.
We install pyenv: https://github.com/pyenv/pyenv-installer
pyenv install 3.9.0 pyenv global 3.9.0
Install project dependencies
python3 -m venv .venv source .venv/bin/activate pip install -r requirements-dev.txt
Testing connection
To understand how it works, we will test the use of the awslocal
command, which is a wrapper for the AWS CLI provided by LocalStack to keep the connections to our local stack and the Cloud stack well separated.
awslocal s3 ls
The stack log will show this:
Ready.
2024-09-03T09:53:20.688 INFO --- [et.reactor-0] localstack.utils.bootstrap : Execution of "_load_service_plugin" took 706.66ms
2024-09-03T09:53:20.688 INFO --- [et.reactor-0] localstack.utils.bootstrap : Execution of "require" took 706.99ms
2024-09-03T09:53:20.792 INFO --- [et.reactor-0] localstack.request.aws : AWS s3.ListBuckets => 200
To continue investigating, we check which user is connected…
(.venv) ~/workspace/sample-serverless-image-resizer-s3-lambda (main)$ awslocal sts get-caller-identity
{
"UserId": "AKIAIOSFODNN7EXAMPLE",
"Account": "000000000000",
"Arn": "arn:aws:iam::000000000000:root" # Cuenta y usuario
}
In the LocalStack log, we will find…
2024-09-03T10:17:03.212 INFO --- [et.reactor-0] localstack.request.aws : AWS sts.GetCallerIdentity => 200
Deploy the Services in our LocalStack
We modify the file
bin/
deploy.sh
, replacing the Python versions with 3.9#bin/deploy.sh # ... configure the python version to 3.9 awslocal lambda create-function \ --function-name presign \ --runtime python3.9 \ --timeout 10 \ --zip-file fileb://lambdas/presign/lambda.zip \ --handler handler.handler \ --role arn:aws:iam::000000000000:role/lambda-role \ --environment Variables="{STAGE=local}" # ...
Run
bin/
deploy.sh
This command deploys the following architecture:
Testing the Image Resizing Stack and reviewing how LocalStack works
- We can view the information we have deployed: By accessing this URL, which is automatically brought up by LocalStack, we will have an overview of the services we have deployed.
You can access each service, where you can find a panel with a list of resources and details for each one; for example, the Lambdas we have deployed:
- Testing that the image resizing app we deployed is working correctly
The output from the installer provides the following information:
make_bucket: webapp upload: website/index.html to s3://webapp/index.html upload: website/app.js to s3://webapp/app.js upload: website/favicon.ico to s3://webapp/favicon.ico Fetching function URL for 'presign' Lambda... http://9htiqm8nu1kb6rwjyl12ymf0574bv7mp.lambda-url.us-east-1.localhost.localstack.cloud:4566/ Fetching function URL for 'list' Lambda... http://632bfbyw4si5k354zabiydf4oj8lt9oo.lambda-url.us-east-1.localhost.localstack.cloud:4566/ Now open the Web app under https://webapp.s3-website.localhost.localstack.cloud:4566/ and paste the function URLs above (make sure to use https:// as protocol)
By following the steps, we have the process of detecting the Lambda endpoints, and if we upload an image, its corresponding Resized Image as shown in the image below.
Conclusions
We tested the LocalStack application by deploying a complete stack provided for testing, and it works correctly. We tested the Lambda, S3, and SNS services.
The user experience is good, with a lot of information.
It is necessary to be logged in, even without a PRO license, to make the most of the app.
A very interesting tool that I will continue to test, especially with infrastructure-as-code tools, to validate which ones can be integrated and how they behave.