LocalStack — Getting Started

Develop and test the AWS application offline

Anh Tu (James) Nguyen
5 min readJan 6, 2024

Today I’m going to share my journey about LocalStack, an useful tool for software engineer to develop and run the AWS applications offline.

What is LocalStack?

According to their official documentation:

LocalStack is a cloud service emulator that runs in a single container on your laptop or in your CI environment. With LocalStack, you can run your AWS applications or Lambdas entirely on your local machine without connecting to a remote cloud provider!

Whether you are testing complex CDK applications or Terraform configurations, or just beginning to learn about AWS services, LocalStack helps speed up and simplify your testing and development workflow.

This is an useful tool which helps you test your applications, before deploying it into a real AWS environment, or for anyone who wants to explore AWS services without paying the bill to them.

Check out this link https://docs.localstack.cloud/user-guide/aws/feature-coverage/ for a full list of AWS services supported by LocalStack. There are some services only available for a Pro license, but Community license should be enough for us to explore.

Installation

LocalStack CLI is the fastest way to start, make sure you have Docker installed and running on your machine.

The CLI starts and manages the LocalStack docker container, you can refer to their alternative installation instructions.

I’m using a MacBook, so all of my steps are following the instructions for MacOS.

  • Run this command to install the LocalStack CLI:
$ brew install localstack/tap/localstack-cli
  • (Optional) Run or add this command to your ~/.zshrc to enable the autocomplete:
$ localstack completion zsh > "${fpath[1]}/_localstack"
  • Start the LocalStack container (can add option -d to start in the background):
$ localstack start

__ _______ __ __
/ / ____ _________ _/ / ___// /_____ ______/ /__
/ / / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/
/ /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,<
/_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_|

💻 LocalStack CLI 3.0.2

[03:41:17] starting LocalStack in Docker mode 🐳 localstack.py:495
────────────────────────────────── LocalStack Runtime Log (press CTRL-C to quit) ───────────────────────────────────

LocalStack version: 3.0.3.dev
LocalStack Docker container id: c014685522ba
LocalStack build date: 2024-01-05
LocalStack build git hash: f9778b3d

2024-01-06T11:41:19.889 INFO --- [-functhread4] hypercorn.error : Running on https://0.0.0.0:4566 (CTRL + C to quit)
2024-01-06T11:41:19.889 INFO --- [-functhread4] hypercorn.error : Running on https://0.0.0.0:4566 (CTRL + C to quit)
Ready.
  • LocalStack container will start an endpoint URL as https://localhost:4566 or https://localhost.localstack.cloud:4566, which is being used by AWS CLI or SDK to emulate AWS services. There are also pre-defined external services port set to 4510-4599.
  • Verify the endpoint health/info:
$ curl --silent https://localhost.localstack.cloud:4566/_localstack/info | jq
{
"version": "3.0.3.dev:f9778b3d",
"edition": "community",
"is_license_activated": false,
"session_id": "b5b6d634-49e4-4a06-87b4-1c306cc89af0",
"machine_id": "dkr_1a2b45381dfb",
"system": "linux",
"is_docker": true,
"server_time_utc": "2024-01-06T12:33:04",
"uptime": 5
}
$ curl --silent https://localhost.localstack.cloud:4566/_localstack/health | jq
{
"services": {
"acm": "available",
"apigateway": "available",
"cloudformation": "available",
"cloudwatch": "available",
"config": "available",
"dynamodb": "available",
"dynamodbstreams": "available",
"ec2": "available",
"es": "available",
"events": "available",
"firehose": "available",
"iam": "available",
"kinesis": "available",
"kms": "available",
"lambda": "available",
"logs": "available",
"opensearch": "available",
"redshift": "available",
"resource-groups": "available",
"resourcegroupstaggingapi": "available",
"route53": "available",
"route53resolver": "available",
"s3": "available",
"s3control": "available",
"scheduler": "available",
"secretsmanager": "available",
"ses": "available",
"sns": "available",
"sqs": "available",
"ssm": "available",
"stepfunctions": "available",
"sts": "available",
"support": "available",
"swf": "available",
"transcribe": "available"
},
"edition": "community",
"version": "3.0.3.dev"
}
  • We can also use CLI to verify:
$ localstack status
┌─────────────────┬───────────────────────────────────────────────────────┐
│ Runtime version │ 3.0.3.dev │
│ Docker image │ tag: latest, id: 2251634cd8ac, 📆 2024-01-05T21:35:00 │
│ Runtime status │ ✔ running (name: "localstack-main", IP: 172.17.0.2) │
└─────────────────┴───────────────────────────────────────────────────────┘
$ localstack status services
┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Service ┃ Status ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│ acm │ ✔ available │
│ apigateway │ ✔ available │
│ cloudformation │ ✔ available │
│ cloudwatch │ ✔ available │
│ config │ ✔ available │
│ dynamodb │ ✔ available │
│ dynamodbstreams │ ✔ available │
│ ec2 │ ✔ available │
│ es │ ✔ available │
│ events │ ✔ available │
│ firehose │ ✔ available │
│ iam │ ✔ available │
│ identitystore │ ✔ available │
│ kinesis │ ✔ available │
│ kms │ ✔ available │
│ lambda │ ✔ available │
│ logs │ ✔ available │
│ opensearch │ ✔ available │
│ redshift │ ✔ available │
│ resource-groups │ ✔ available │
│ resourcegroupstaggingapi │ ✔ available │
│ route53 │ ✔ available │
│ route53resolver │ ✔ available │
│ s3 │ ✔ available │
│ s3control │ ✔ available │
│ scheduler │ ✔ available │
│ secretsmanager │ ✔ available │
│ ses │ ✔ available │
│ sns │ ✔ available │
│ sqs │ ✔ available │
│ ssm │ ✔ available │
│ sso-admin │ ✔ available │
│ stepfunctions │ ✔ available │
│ sts │ ✔ available │
│ support │ ✔ available │
│ swf │ ✔ available │
│ transcribe │ ✔ available │
└──────────────────────────┴─────────────┘

Usage

Now we can configure AWS profile and start using LocalStack:

  • Append these lines into your ~/.aws/config:
[profile localstack]
output = json
region = us-east-1
endpoint_url = https://localhost.localstack.cloud:4566
cli_pager=
  • Add the default AWS Access and Secret key of LocalStack into ~/.aws/credentials:
[localstack]
aws_access_key_id=test
aws_secret_access_key=test

The first example is creating a static website hosted in S3:

  • Created new S3 bucket:
$ AWS_PROFILE=localstack aws s3api create-bucket --bucket james
{
"Location": "/james"
}
$ AWS_PROFILE=localstack aws s3 ls s3://
2024-01-06 05:00:28 james
  • Create a sample index.html with following content:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to James' home</title>
</head>
<body>
<p>This is an example webpage to test a S3 static webapp in LocalStack.</p>
</body>
</html>
  • Upload the file into S3 and make it as static website:
$ AWS_PROFILE=localstack aws s3 cp index.html s3://james
upload: ./index.html to s3://james/index.html
$ AWS_PROFILE=localstack aws s3 website s3://james --index-document index.html
  • Now we can test the website by opening this URL https://james.s3-website.localhost.localstack.cloud:4566:
$ curl https://james.s3-website.localhost.localstack.cloud:4566
<!DOCTYPE html>
<html>
<head>
<title>Welcome to James' home</title>
</head>
<body>
<p>This is an example webpage to test a S3 static webapp in LocalStack.</p>
</body>
</html>

Conclusion

In this post, I hope you have an initial idea and understand how the LocalStack works. In next articles, I will try with other AWS services, and show how to integrate LocalStack with Terraform.

--

--