LocalStack — Getting Started
Develop and test the AWS application offline
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
orhttps://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 to4510-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.