diff --git a/src/content/docs/aws/getting-started/ai-workflows.mdx b/src/content/docs/aws/getting-started/ai-workflows.mdx
new file mode 100644
index 00000000..4746e4ff
--- /dev/null
+++ b/src/content/docs/aws/getting-started/ai-workflows.mdx
@@ -0,0 +1,73 @@
+---
+title: AI & Agent Workflows
+description: Use LocalStack with AI coding assistants, MCP servers, and agent-driven infrastructure automation.
+template: doc
+sidebar:
+ order: 6
+---
+
+## Overview
+
+LocalStack is a natural fit for AI-assisted development workflows.
+Whether you're using an AI coding assistant to generate infrastructure code, running an agent that deploys AWS resources, or validating AI-generated Terraform before applying it to real AWS — LocalStack gives you a safe, fast, cost-free environment to do it in.
+
+## Connect an AI coding assistant via MCP
+
+The [LocalStack MCP Server](https://github.com/localstack/localstack-mcp-server) exposes LocalStack's API as an MCP (Model Context Protocol) tool server.
+This lets AI assistants like Claude, Cursor, Windsurf, or any MCP-compatible tool inspect and interact with your running LocalStack instance directly.
+
+With the MCP server connected, your AI assistant can:
+
+- List running AWS services and deployed resources
+- Create, update, and delete resources in your local environment
+- Query resource state to understand what's already deployed
+- Help you debug issues by inspecting live infrastructure
+
+**Quick setup:**
+
+```bash
+# Install the LocalStack MCP server
+pip install localstack-mcp-server
+```
+
+Then add it to your AI tool's MCP configuration.
+See the [localstack-mcp-server README](https://github.com/localstack/localstack-mcp-server) for tool-specific setup instructions for Claude, Cursor, and others.
+
+:::note
+The MCP server connects to a running LocalStack instance — make sure LocalStack is started first with `lstk start` or `localstack start`.
+:::
+
+## Deploy with agent-driven automation using Skills
+
+[LocalStack Skills](https://github.com/localstack/skills) are pre-built agent skill definitions for deploying common AWS architectures locally.
+Instead of stepping through manual CLI commands, you describe what you want and an agent handles the deployment.
+
+Skills are useful when:
+
+- You want to scaffold a new local environment quickly without writing all the infrastructure code yourself
+- You're using an agent-first workflow and want LocalStack to be a first-class deployment target
+- You want to iterate rapidly on architecture without touching real AWS
+
+Browse the [skills repository](https://github.com/localstack/skills) for available skills and setup instructions.
+
+## Validate AI-generated IaC before applying to AWS
+
+A common pattern when using AI to generate Terraform, CDK, or CloudFormation is to deploy it to LocalStack first.
+This catches configuration errors, missing permissions, and service interaction bugs before you spend time (and money) deploying to real AWS.
+
+The workflow is:
+
+1. Generate infrastructure code with your AI tool
+2. Deploy to LocalStack with `tflocal apply` (Terraform), `cdklocal deploy` (CDK), or the AWS CLI
+3. Run your integration tests against the local environment
+4. When everything passes, deploy to real AWS with confidence
+
+See [Tooling](/aws/tooling/) for the full list of LocalStack-aware wrappers for common IaC tools.
+
+## Summary
+
+| Use case | Tool |
+|---|---|
+| AI assistant that can inspect & manage local resources | [LocalStack MCP Server](https://github.com/localstack/localstack-mcp-server) |
+| Agent-driven infrastructure deployment | [LocalStack Skills](https://github.com/localstack/skills) |
+| Validate AI-generated IaC safely | LocalStack + `tflocal` / `cdklocal` / `awslocal` |
diff --git a/src/content/docs/aws/getting-started/auth-token.mdx b/src/content/docs/aws/getting-started/auth-token.mdx
index b71c45a1..4f6446c0 100644
--- a/src/content/docs/aws/getting-started/auth-token.mdx
+++ b/src/content/docs/aws/getting-started/auth-token.mdx
@@ -3,7 +3,7 @@ title: Auth Token
description: Configure your Auth Token to access and activate LocalStack.
template: doc
sidebar:
- order: 3
+ order: 4
---
import { Code, Tabs, TabItem } from '@astrojs/starlight/components';
diff --git a/src/content/docs/aws/getting-started/ci-cd.mdx b/src/content/docs/aws/getting-started/ci-cd.mdx
new file mode 100644
index 00000000..feac5951
--- /dev/null
+++ b/src/content/docs/aws/getting-started/ci-cd.mdx
@@ -0,0 +1,185 @@
+---
+title: CI/CD Setup
+description: Run LocalStack in CI pipelines — auth tokens, Docker Compose, and GitHub Actions examples.
+template: doc
+sidebar:
+ order: 5
+---
+
+import { Tabs, TabItem } from '@astrojs/starlight/components';
+
+## Overview
+
+LocalStack works great in CI environments.
+The setup differs from local development in a few important ways:
+
+- **Use a CI Auth Token**, not your personal Developer token
+- **Manage the container directly** via Docker Compose or `docker run` — `lstk` and the LocalStack Desktop are local-only tools
+- **LocalStack is ephemeral by default** — each CI run starts fresh, which is usually exactly what you want for reproducible tests
+
+## Step 1 — Get a CI Auth Token
+
+CI pipelines should use a dedicated CI Auth Token, not a Developer token tied to a specific user.
+
+1. Go to the [Auth Tokens page](https://app.localstack.cloud/workspace/auth-tokens) in the LocalStack Web Application
+2. Create a new **CI Auth Token**
+3. Add it as a secret in your CI provider (e.g., `LOCALSTACK_AUTH_TOKEN`)
+
+:::danger[Keep your token secret]
+Never commit an auth token to source control.
+Always inject it via your CI provider's secrets or environment variable mechanism.
+If a token is compromised, rotate it immediately on the Auth Tokens page — old tokens are invalidated instantly.
+:::
+
+See the [Auth Token documentation](/aws/getting-started/auth-token/) for full details on token types and configuration.
+
+## Step 2 — Start LocalStack in CI
+
+
+
+ The recommended approach is to start LocalStack as a service container or as a step using the official GitHub Action:
+
+ ```yaml
+ # .github/workflows/integration-tests.yml
+ name: Integration Tests
+
+ on: [push, pull_request]
+
+ jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Start LocalStack
+ uses: LocalStack/setup-localstack@v0.2
+ with:
+ image-tag: latest
+ env:
+ LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
+
+ - name: Run tests
+ run: |
+ # Your test commands here, e.g.:
+ pip install awscli-local
+ awslocal s3 mb s3://my-test-bucket
+ pytest tests/integration/
+ ```
+
+ The `setup-localstack` action handles pulling the image, starting the container, and waiting for LocalStack to be ready.
+
+
+ Add LocalStack as a service in your `docker-compose.yml`:
+
+ ```yaml
+ services:
+ localstack:
+ container_name: localstack-main
+ image: localstack/localstack-pro
+ ports:
+ - "127.0.0.1:4566:4566"
+ - "127.0.0.1:4510-4559:4510-4559"
+ - "127.0.0.1:443:443"
+ environment:
+ - LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:?}
+ - DEBUG=${DEBUG:-0}
+ volumes:
+ - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
+ - "/var/run/docker.sock:/var/run/docker.sock"
+ ```
+
+ Start it and wait for readiness:
+
+ ```bash
+ docker compose up -d localstack
+ # Wait for LocalStack to be ready
+ until curl -s http://localhost:4566/_localstack/health | grep -q '"running"'; do sleep 1; done
+ ```
+
+ :::note
+ Mounting `/var/run/docker.sock` is required for Lambda emulation, which uses Docker to run function containers.
+ :::
+
+
+ Start LocalStack directly with `docker run`:
+
+ ```bash
+ docker run \
+ --rm -d \
+ --name localstack-main \
+ -p 127.0.0.1:4566:4566 \
+ -p 127.0.0.1:4510-4559:4510-4559 \
+ -e LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:?} \
+ -v /var/run/docker.sock:/var/run/docker.sock \
+ localstack/localstack-pro
+
+ # Wait for readiness
+ until curl -s http://localhost:4566/_localstack/health | grep -q '"running"'; do sleep 1; done
+ ```
+
+
+ Add LocalStack as a service in your CircleCI config:
+
+ ```yaml
+ version: 2.1
+
+ jobs:
+ integration-tests:
+ docker:
+ - image: cimg/python:3.12
+ - image: localstack/localstack-pro
+ environment:
+ LOCALSTACK_AUTH_TOKEN: $LOCALSTACK_AUTH_TOKEN
+ steps:
+ - checkout
+ - run:
+ name: Wait for LocalStack
+ command: |
+ until curl -s http://localhost:4566/_localstack/health | grep -q '"running"'; do sleep 1; done
+ - run:
+ name: Run tests
+ command: pytest tests/integration/
+ ```
+
+ Set `LOCALSTACK_AUTH_TOKEN` in your CircleCI project's environment variables.
+
+
+
+## Verify activation
+
+After LocalStack starts, confirm the license is active:
+
+```bash
+curl -s http://localhost:4566/_localstack/info | jq '.is_license_activated'
+# Should return: true
+```
+
+## Key differences from local development
+
+| | Local development | CI/CD |
+|---|---|---|
+| **CLI** | `lstk` or LocalStack CLI | Docker Compose / `docker run` |
+| **Auth** | Browser login or stored token | `LOCALSTACK_AUTH_TOKEN` env var |
+| **Token type** | Developer token | CI token |
+| **State** | Optional persistence | Ephemeral (fresh per run) |
+| **Startup** | Interactive TUI | `--non-interactive` / `-d` flag |
+
+## Persisting state across runs
+
+By default, LocalStack starts fresh on every run — all resources are gone when the container stops.
+This is ideal for most CI use cases (clean, reproducible tests).
+
+If you need to share state across runs (e.g., seed data, pre-built infrastructure), look at [Cloud Pods](/aws/capabilities/state-management/cloud-pods/), which let you snapshot and restore LocalStack state.
+
+## More CI integrations
+
+LocalStack has dedicated integration guides for many CI providers:
+
+- [GitHub Actions](/aws/integrations/continuous-integration/github-actions/)
+- [GitLab CI](/aws/integrations/continuous-integration/gitlab-ci/)
+- [CircleCI](/aws/integrations/continuous-integration/circleci/)
+- [AWS CodeBuild](/aws/integrations/continuous-integration/codebuild/)
+- [Travis CI](/aws/integrations/continuous-integration/travis-ci/)
+- [Bitbucket Pipelines](/aws/integrations/continuous-integration/bitbucket/)
+
+See the full [CI/CD integrations](/aws/integrations/continuous-integration/) section for details.
diff --git a/src/content/docs/aws/getting-started/faq.mdx b/src/content/docs/aws/getting-started/faq.mdx
index 12128b64..3eded1df 100644
--- a/src/content/docs/aws/getting-started/faq.mdx
+++ b/src/content/docs/aws/getting-started/faq.mdx
@@ -3,7 +3,7 @@ title: FAQ
description: Frequently asked questions about LocalStack for AWS.
template: doc
sidebar:
- order: 5
+ order: 7
---
import { Tabs, TabItem } from '@astrojs/starlight/components';
diff --git a/src/content/docs/aws/getting-started/help-support.md b/src/content/docs/aws/getting-started/help-support.md
index c6641003..d2dde0db 100644
--- a/src/content/docs/aws/getting-started/help-support.md
+++ b/src/content/docs/aws/getting-started/help-support.md
@@ -3,7 +3,7 @@ title: Help & Support
description: Get help and support with LocalStack.
template: doc
sidebar:
- order: 6
+ order: 8
---
## Introduction
diff --git a/src/content/docs/aws/getting-started/index.md b/src/content/docs/aws/getting-started/index.md
deleted file mode 100644
index 017debdb..00000000
--- a/src/content/docs/aws/getting-started/index.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: Overview
-description: This section describes how to get started with LocalStack using a variety of options, and provides details on how LocalStack can be configured to fit the needs of a local cloud sandbox for development, testing, and experimentation.
-template: doc
-editUrl: false
-sidebar:
- order: 1
----
-
-[LocalStack](https://localstack.cloud) 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.
-
-LocalStack supports a growing number of [AWS services](/aws/services/)
-, like [Lambda](/aws/services/lambda), [S3](/aws/services/s3), [DynamoDB](/aws/services/dynamodb), [Kinesis](/aws/services/kinesis), [SQS](/aws/services/sqs), [SNS](/aws/services/sns), and more!
-[LocalStack for AWS](https://localstack.cloud/pricing) also supports APIs and advanced features to make your cloud development experience a breeze.
-
-You can find a comprehensive list of supported APIs on each AWS service page.
-
-LocalStack also provides additional features to make your life as a cloud developer easier!
-
-Check out LocalStack's [Cloud Developer Tools](/aws/tooling/).
diff --git a/src/content/docs/aws/getting-started/index.mdx b/src/content/docs/aws/getting-started/index.mdx
new file mode 100644
index 00000000..4b0e2503
--- /dev/null
+++ b/src/content/docs/aws/getting-started/index.mdx
@@ -0,0 +1,48 @@
+---
+title: Overview
+description: This section describes how to get started with LocalStack for AWS using a variety of options, and provides details on how LocalStack can be configured to fit the needs of a local cloud sandbox for development, testing, and experimentation.
+template: doc
+editUrl: false
+sidebar:
+ order: 1
+---
+
+import { SectionCards } from '../../../../components/SectionCards.tsx';
+
+[LocalStack for AWS](https://localstack.cloud) is a cloud service emulator that runs in a single container on your laptop or in your CI environment.
+It gives you a fully functional AWS environment — Lambda, DynamoDB, S3, SQS, and [80+ more services](/aws/services/) — without touching a real AWS account and without incurring cloud costs.
+
+Here's why developers and teams use it:
+
+- **Faster development loops** — Test changes against local AWS services instantly, without waiting on real deployments or worrying about cloud costs.
+- **Integration testing in CI** — Run real integration tests against local AWS infrastructure in every pull request, catching bugs before they reach production.
+- **Validate IaC before applying** — Deploy your Terraform, CDK, or CloudFormation to LocalStack first. Confirm it works the way you expect before applying to a real AWS environment.
+- **Safe experimentation** — Explore new AWS services and architectures freely, with no risk to production systems.
+
+LocalStack for AWS also includes advanced capabilities for teams: [Cloud Pods](/aws/capabilities/state-management/cloud-pods/) for sharing and restoring state, [IAM policy enforcement](/aws/capabilities/security-testing/iam-policy-enforcement/), [Chaos Engineering](/aws/capabilities/chaos-engineering/), and more.
+
+## Choose your path
+
+
diff --git a/src/content/docs/aws/getting-started/installation.mdx b/src/content/docs/aws/getting-started/installation.mdx
index 4e76ecba..dcc080ab 100644
--- a/src/content/docs/aws/getting-started/installation.mdx
+++ b/src/content/docs/aws/getting-started/installation.mdx
@@ -1,24 +1,68 @@
---
title: Installation
-description: Basic installation guide to get started with LocalStack on your local machine.
+description: All installation methods for LocalStack — lstk, LocalStack CLI, Docker Compose, Docker, and Helm.
template: doc
sidebar:
- order: 2
+ order: 3
---
import { Code, LinkButton, Tabs, TabItem } from '@astrojs/starlight/components';
import { LOCALSTACK_VERSION } from "astro:env/server";
-## LocalStack CLI
+## Local development
-The quickest way get started with LocalStack is by using the LocalStack CLI.
-It allows you to start LocalStack from your command line.
+There are two CLI options for running LocalStack on your laptop. Start with `lstk` if you want the fastest path to a running instance, or use the LocalStack CLI if you need full feature support.
+
+### lstk
+
+`lstk` is a lightweight, Go-based CLI that handles the full startup sequence in one command: browser-based login, image pull, and container launch.
+It's the fastest way to get LocalStack running locally.
+
+:::caution[Early release]
+`lstk` currently supports core lifecycle commands (`start`, `stop`, `logs`, `status`).
+For advanced features like Cloud Pods, Extensions, and Ephemeral Instances, use the [LocalStack CLI](#localstack-cli) instead.
+Both tools can coexist on the same system.
+:::
+
+Install `lstk`:
+
+
+
+ ```bash
+ brew install localstack/tap/lstk
+ ```
+
+
+ ```bash
+ npm install -g @localstack/lstk
+ ```
+
+
+ Download a pre-built binary for your platform from [GitHub Releases](https://github.com/localstack/lstk/releases) and add it to your `PATH`.
+
+
+
+Start LocalStack:
+
+```bash
+lstk start
+```
+
+On first run, `lstk` opens a browser login flow.
+After authenticating, it pulls the LocalStack image and starts the container.
+Subsequent starts use the stored credential from your system keyring — no manual token management needed.
+
+---
+
+### LocalStack CLI
+
+The full-featured LocalStack CLI gives you access to all LocalStack capabilities.
Please make sure that you have a working [Docker installation](https://docs.docker.com/get-docker/) on your machine before moving on.
### Installing LocalStack CLI
The CLI starts and manages the LocalStack Docker container.
-For alternative methods of managing the LocalStack container, see our [alternative installation instructions](#alternatives).
+For alternative methods of managing the LocalStack container, see our [alternative installation instructions](#ci-and-server-environments).
@@ -196,30 +240,25 @@ Updating the LocalStack CLI using `localstack update localstack-cli` and `locals
If it was installed using the pre-built binary or via Brew, please run the installation steps again to update to the latest version.
:::
-## Alternatives
-
-Besides using the CLI, there are other ways of starting and managing your LocalStack instance:
-
-- [LocalStack Desktop](#localstack-desktop)\
- Get a desktop experience and work with your local LocalStack instance via the UI.
+## CI and server environments
-- [LocalStack Docker Extension](#localstack-docker-extension)\
- Use the LocalStack extension for Docker Desktop to work with your LocalStack instance.
+For CI pipelines and server deployments, you'll manage the LocalStack container directly rather than using a local CLI.
+See the [CI/CD Setup guide](/aws/getting-started/ci-cd/) for a complete walkthrough including GitHub Actions examples.
-- [Docker-Compose](#docker-compose)\
- Use Docker Compose to configure and start your LocalStack Docker container.
+The options below cover the main container management approaches:
-- [Docker](#docker)\
- Use the Docker CLI to manually start the LocalStack Docker container.
+- [Docker Compose](#docker-compose) — recommended for CI and team environments
+- [Docker](#docker) — direct container control for scripted setups
+- [Helm](#helm) — deploy LocalStack in a Kubernetes cluster
-- [Helm](#helm)\
- Use Helm to create a LocalStack deployment in a Kubernetes cluster.
+The LocalStack emulator is available on Docker Hub as `localstack/localstack-pro`.
-LocalStack runs inside a Docker container, and the above options are different ways to start and manage the LocalStack Docker container.
+For a comprehensive overview of LocalStack images, see the [Docker images documentation](/aws/capabilities/config/docker-images).
-The LocalStack emulator is available on Docker Hub (`localstack/localstack-pro`).
+## GUI tools
-For a comprehensive overview of the LocalStack images, check out our [Docker images documentation](/aws/capabilities/config/docker-images).
+- [LocalStack Desktop](#localstack-desktop) — desktop UI for managing your local instance
+- [LocalStack Docker Extension](#localstack-docker-extension) — manage LocalStack from Docker Desktop
### LocalStack Desktop
diff --git a/src/content/docs/aws/getting-started/quickstart.mdx b/src/content/docs/aws/getting-started/quickstart.mdx
index 7774291f..687b8733 100644
--- a/src/content/docs/aws/getting-started/quickstart.mdx
+++ b/src/content/docs/aws/getting-started/quickstart.mdx
@@ -1,361 +1,299 @@
---
title: Quickstart
-description: How to run an AWS application on your local machine and test local cloud development with LocalStack.
+description: Deploy a serverless API locally with LocalStack in under 10 minutes using Lambda and DynamoDB.
template: doc
sidebar:
- order: 4
+ order: 2
---
-import { Code, LinkButton, Tabs, TabItem } from '@astrojs/starlight/components';
-## Introduction
-
-In this quickstart guide, we'll walk you through the process of starting LocalStack on your local machine and deploying a [serverless image resizer application](https://github.com/localstack-samples/sample-serverless-image-resizer-s3-lambda) that utilizes several AWS services.
-This guide aims to help you understand how to use LocalStack for the development and testing of your AWS applications locally.
-It introduces you to the following key concepts:
-
-- Starting a LocalStack instance on your local machine.
-- Deploying an AWS serverless application infrastructure locally.
-- Running an automated integration test suite against local infrastructure.
-- Exploring the LocalStack Web Application to view deployed resources.
-- Destroying the local infrastructure you have provisioned.
+import { Tabs, TabItem } from '@astrojs/starlight/components';
-## Architecture
-
-The following diagram shows the architecture that we will deploy locally using LocalStack:
+## Introduction
-
+In this quickstart you'll start LocalStack and deploy a simple serverless API — a **Lambda function backed by DynamoDB** — entirely on your local machine.
+No AWS account needed.
-The architecture:
+By the end you will have:
-- Configures S3 bucket notifications to invoke a Lambda function.
-- Provides S3 pre-signed POST URLs for direct uploads to the S3 bucket.
-- Creates S3 website hosting for serving the static application client.
-- Configures direct invocation URLs for Lambda functions accessible to the client.
-- Establishes Lambda SNS to SNS topic notifications for failure handling.
-- Creates SNS to SES subscriptions for email notifications triggered by specific events.
+- LocalStack running locally in Docker
+- A Lambda function deployed and invokable via a public URL
+- A DynamoDB table storing data written by the Lambda
+- Confirmed that your local environment behaves like real AWS
-An internal SES LocalStack testing endpoint (`/_localstack/aws/ses`) is configured as well, to test email sending functionality while running our local integration test suite.
+Choose your preferred deployment style below: **AWS CLI** (`awslocal`) or **Terraform** (`tflocal`).
## Prerequisites
-- [LocalStack CLI](/aws/getting-started/installation/#installing-localstack-cli)
-- [LocalStack Web Application account](https://app.localstack.cloud/sign-up) & [Auth Token](/aws/getting-started/auth-token/)
-- [Docker](https://docs.docker.com/get-docker/)
-- [Python 3.11+](https://www.python.org/downloads/) & `pip`
-- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) & [`awslocal` wrapper](/aws/integrations/aws-native-tools/aws-cli/#localstack-aws-cli-awslocal)
-- `jq`, `zip` & `curl`
+- [Docker](https://docs.docker.com/get-docker/) installed and running
+- A [LocalStack account](https://app.localstack.cloud/sign-up)
-You can start LocalStack using the `localstack` CLI.
-Start the LocalStack for AWS container with your `LOCALSTACK_AUTH_TOKEN` pre-configured:
+## Step 1 — Install and start LocalStack
-
-
- \nlocalstack start`} lang="shell" />
-
-
- \nlocalstack start`} lang="shell" />
-
-
+The fastest way to get LocalStack running locally is with `lstk`, a lightweight CLI that handles authentication and image setup automatically.
-If you prefer running LocalStack in detached mode, you can add the `-d` flag to the `localstack start` command, and use Docker Desktop to view the logs.
+
+
+ Install `lstk`:
-## Instructions
+ ```bash
+ brew install localstack/tap/lstk # macOS / Linux with Homebrew
+ ```
-To get started, clone the sample application repository from GitHub:
+ ```bash
+ npm install -g @localstack/lstk # or via npm
+ ```
-```bash
-git clone https://github.com/localstack-samples/sample-serverless-image-resizer-s3-lambda.git
-cd sample-serverless-image-resizer-s3-lambda
-```
+ Then start LocalStack:
-You can now follow the instructions below to start LocalStack, deploy the sample application, and test the application.
+ ```bash
+ lstk start
+ ```
-### Setup a virtual environment
+ On first run, `lstk` opens a browser login to authenticate, then pulls the image and starts the container automatically.
-To deploy the sample application, you need to have specific Python packages are installed.
-It is advisable to utilize a virtual environment for the installation process, allowing the packages to be installed in an isolated environment.
-Execute the following commands to create a virtual environment and install the packages in `requirements-dev.txt`:
+ :::note[Early release]
+ `lstk` currently supports core lifecycle commands (start, stop, logs, status).
+ For advanced features like Cloud Pods, Extensions, and Ephemeral Instances, use the [LocalStack CLI](/aws/getting-started/installation/#localstack-cli) instead.
+ :::
-
-
- ```shell
- python -m venv .venv
- source .venv/bin/activate
- pip install -r requirements-dev.txt
- ```
-
- ```shell
- python -m venv .venv
- .venv\Scripts\activate
- pip install -r requirements-dev.txt
+
+ If you prefer the full-featured LocalStack CLI, [install it first](/aws/getting-started/installation/#localstack-cli), then [configure your auth token](/aws/getting-started/auth-token/), and start LocalStack:
+
+ ```bash
+ localstack start
```
+
-:::tip
-If you are encountering issues with the installation of the packages, such as Pillow, ensure you use the same version as the Python Lambdas (3.11.6) for Pillow to work.
-If you're using pyenv, install and activate Python 3.11 with the following commands:
-```bash
-pyenv install 3.11
-pyenv global 3.11
-```
-:::
-
-### Setup the serverless image resizer
-
-This application enables serverless image resizing using [S3](/aws/services/s3/), [SSM](/aws/services/ssm/), [Lambda](/aws/services/lambda/), [SNS](/aws/services/sns/), and [SES](/aws/services/ses/).
-A simple web interface allows users to upload and view resized images.
-A Lambda function generates S3 pre-signed URLs for direct uploads, while S3 bucket notifications trigger image resizing.
-Another Lambda function lists and provides pre-signed URLs for browser display.
-The application also handles Lambda failures through SNS and SES email notifications.
-
-The sample application uses AWS CLI and our `awslocal` wrapper to deploy the application to LocalStack.
-Before going further, you need to build your Lambda functions.
-You can use the following script that will cover all three of them:
+Wait for the container to report ready — you'll see a log line like `Ready.` or you can verify with:
```bash
-deployment/build-lambdas.sh
+curl -s http://localhost:4566/_localstack/health | grep '"running"'
```
-You can now deploy the sample application on LocalStack by running the following command:
+## Step 2 — Deploy the serverless API
-```bash
-deployment/awslocal/deploy.sh
-```
+Now deploy a Lambda function and a DynamoDB table. Pick the tooling you prefer:
-Alternatively, you can follow these instructions to deploy the sample application manually step-by-step.
+
+
+ Install the `awslocal` wrapper if you haven't already:
-:::tip
-In absence of the `awslocal` wrapper, you can use the `aws` CLI directly, by configuring an [endpoint URL](/aws/integrations/aws-native-tools/aws-cli/#configuring-an-endpoint-url) or a [custom profile](/aws/integrations/aws-native-tools/aws-cli/#configuring-a-custom-profile) like `localstack`.
-You can then swap `awslocal` with `aws --endpoint-url=http://localhost:4566` or `aws --profile=localstack` in the commands below.
-:::
+ ```bash
+ pip install awscli-local
+ ```
-#### Create the S3 buckets
+ **Create the Lambda function:**
+
+ ```bash
+ mkdir -p /tmp/localstack-demo
+ cat > /tmp/localstack-demo/handler.py << 'EOF'
+ import json, boto3, os, uuid
+
+ def handler(event, context):
+ table = boto3.resource('dynamodb').Table(os.environ['TABLE_NAME'])
+ method = event.get('requestContext', {}).get('http', {}).get('method', 'GET')
+ if method == 'POST':
+ item = {'id': str(uuid.uuid4()), **json.loads(event.get('body', '{}'))}
+ table.put_item(Item=item)
+ return {'statusCode': 200, 'body': json.dumps(item)}
+ result = table.scan()
+ return {'statusCode': 200, 'body': json.dumps(result['Items'])}
+ EOF
+ cd /tmp/localstack-demo && zip handler.zip handler.py
+ ```
-```bash
-awslocal s3 mb s3://localstack-thumbnails-app-images
-awslocal s3 mb s3://localstack-thumbnails-app-resized
-```
+ **Create the DynamoDB table:**
-#### Add bucket names into the parameter store
+ ```bash
+ awslocal dynamodb create-table \
+ --table-name Messages \
+ --attribute-definitions AttributeName=id,AttributeType=S \
+ --key-schema AttributeName=id,KeyType=HASH \
+ --billing-mode PAY_PER_REQUEST
+ ```
-```bash
-awslocal ssm put-parameter \
- --name /localstack-thumbnail-app/buckets/images \
- --type "String" \
- --value "localstack-thumbnails-app-images"
-awslocal ssm put-parameter \
- --name /localstack-thumbnail-app/buckets/resized \
- --type "String" \
- --value "localstack-thumbnails-app-resized"
-```
+ **Deploy the Lambda:**
-#### Create SNS DLQ Topic for failed lambda invocations
+ ```bash
+ awslocal lambda create-function \
+ --function-name messages-api \
+ --runtime python3.12 \
+ --handler handler.handler \
+ --zip-file fileb:///tmp/localstack-demo/handler.zip \
+ --role arn:aws:iam::000000000000:role/lambda-role \
+ --environment Variables={TABLE_NAME=Messages}
-```bash
-awslocal sns create-topic --name failed-resize-topic
-```
+ awslocal lambda wait function-active --function-name messages-api
+ ```
-To receive immediate alerts in case of image resize failures, subscribe an email address to the system.
-You can use the following command to subscribe an email address to the SNS topic:
+ **Create a public function URL:**
-```bash
-awslocal sns subscribe \
- --topic-arn arn:aws:sns:us-east-1:000000000000:failed-resize-topic \
- --protocol email \
- --notification-endpoint my-email@example.com
-```
+ ```bash
+ awslocal lambda create-function-url-config \
+ --function-name messages-api \
+ --auth-type NONE
+ ```
-#### Create the Presign Lambda
-
-```bash showshowLineNumbers
-(cd lambdas/presign; rm -f lambda.zip; zip lambda.zip handler.py)
-awslocal lambda create-function \
- --function-name presign \
- --runtime python3.11 \
- --timeout 10 \
- --zip-file fileb://lambdas/presign/lambda.zip \
- --handler handler.handler \
- --role arn:aws:iam::000000000000:role/lambda-role \
- --environment Variables="{STAGE=local}"
-awslocal lambda wait function-active-v2 --function-name presign
-awslocal lambda create-function-url-config \
- --function-name presign \
- --auth-type NONE
-```
+ **Retrieve the URL:**
-#### Create the Image List Lambda
-
-```bash showshowLineNumbers
-(cd lambdas/list; rm -f lambda.zip; zip lambda.zip handler.py)
-awslocal lambda create-function \
- --function-name list \
- --handler handler.handler \
- --zip-file fileb://lambdas/list/lambda.zip \
- --runtime python3.11 \
- --timeout 10 \
- --role arn:aws:iam::000000000000:role/lambda-role \
- --environment Variables="{STAGE=local}"
-awslocal lambda wait function-active-v2 --function-name list
-awslocal lambda create-function-url-config \
- --function-name list \
- --auth-type NONE
-```
+ ```bash
+ LAMBDA_URL=$(awslocal lambda list-function-url-configs \
+ --function-name messages-api \
+ --query 'FunctionUrlConfigs[0].FunctionUrl' \
+ --output text)
+ echo $LAMBDA_URL
+ ```
-#### Build the Image Resizer Lambda
+
+
+ Install Terraform and the `tflocal` wrapper:
-
-
- ```bash showshowLineNumbers
- cd lambdas/resize
- rm -rf libs lambda.zip
- docker run --platform linux/x86_64 -v "$PWD":/var/task "public.ecr.aws/sam/build-python3.11" /bin/sh -c "pip install -r requirements.txt -t libs; exit"
- cd libs && zip -r ../lambda.zip . && cd ..
- zip lambda.zip handler.py
- rm -rf libs
- cd ../..
+ ```bash
+ brew install hashicorp/tap/terraform # or see https://developer.hashicorp.com/terraform/install
+ pip install terraform-local
```
-
-
- ```bash showshowLineNumbers
- cd lambdas/resize
- rm -rf package lambda.zip
- mkdir package
- pip install -r requirements.txt -t package --platform manylinux_2_28_x86_64 --python-version 3.11 --no-deps
- zip lambda.zip handler.py
- cd package
- zip -r ../lambda.zip *;
- cd ../..
+
+ Create a project directory and `main.tf`:
+
+ ```bash
+ mkdir -p /tmp/localstack-demo && cd /tmp/localstack-demo
```
-
-
- ```bash showshowLineNumbers
- cd lambdas/resize
- rm -rf package lambda.zip
- mkdir package
- pip install -r requirements.txt -t package
- zip lambda.zip handler.py
- cd package
- zip -r ../lambda.zip\_;
- cd ../..
+
+ ```hcl
+ # main.tf
+ terraform {
+ required_providers {
+ aws = { source = "hashicorp/aws" }
+ archive = { source = "hashicorp/archive" }
+ }
+ }
+
+ resource "aws_dynamodb_table" "messages" {
+ name = "Messages"
+ billing_mode = "PAY_PER_REQUEST"
+ hash_key = "id"
+ attribute {
+ name = "id"
+ type = "S"
+ }
+ }
+
+ data "archive_file" "lambda" {
+ type = "zip"
+ output_path = "${path.module}/handler.zip"
+ source {
+ filename = "handler.py"
+ content = <<-EOF
+ import json, boto3, os, uuid
+ def handler(event, context):
+ table = boto3.resource('dynamodb').Table(os.environ['TABLE_NAME'])
+ method = event.get('requestContext', {}).get('http', {}).get('method', 'GET')
+ if method == 'POST':
+ item = {'id': str(uuid.uuid4()), **json.loads(event.get('body', '{}'))}
+ table.put_item(Item=item)
+ return {'statusCode': 200, 'body': json.dumps(item)}
+ result = table.scan()
+ return {'statusCode': 200, 'body': json.dumps(result['Items'])}
+ EOF
+ }
+ }
+
+ resource "aws_iam_role" "lambda_role" {
+ name = "lambda-role"
+ assume_role_policy = jsonencode({
+ Version = "2012-10-17"
+ Statement = [{ Action = "sts:AssumeRole", Effect = "Allow",
+ Principal = { Service = "lambda.amazonaws.com" } }]
+ })
+ }
+
+ resource "aws_lambda_function" "messages_api" {
+ function_name = "messages-api"
+ runtime = "python3.12"
+ handler = "handler.handler"
+ filename = data.archive_file.lambda.output_path
+ source_code_hash = data.archive_file.lambda.output_base64sha256
+ role = aws_iam_role.lambda_role.arn
+ environment {
+ variables = { TABLE_NAME = aws_dynamodb_table.messages.name }
+ }
+ }
+
+ resource "aws_lambda_function_url" "messages_api" {
+ function_name = aws_lambda_function.messages_api.function_name
+ authorization_type = "NONE"
+ }
+
+ output "function_url" {
+ value = aws_lambda_function_url.messages_api.function_url
+ }
```
-
-
-#### Create the Image Resizer Lambda
-
-```bash showshowLineNumbers
-awslocal lambda create-function \
- --function-name resize \
- --runtime python3.11 \
- --timeout 10 \
- --zip-file fileb://lambdas/resize/lambda.zip \
- --handler handler.handler \
- --dead-letter-config TargetArn=arn:aws:sns:us-east-1:000000000000:failed-resize-topic \
- --role arn:aws:iam::000000000000:role/lambda-role \
- --environment Variables="{STAGE=local}"
-awslocal lambda wait function-active-v2 --function-name resize
-awslocal lambda put-function-event-invoke-config \
- --function-name resize \
- --maximum-event-age-in-seconds 3600 \
- --maximum-retry-attempts 0
-```
+ **Deploy:**
-#### Connect S3 bucket to Resizer Lambda
+ ```bash
+ tflocal init
+ tflocal apply -auto-approve
+ ```
-```bash
-awslocal s3api put-bucket-notification-configuration \
- --bucket localstack-thumbnails-app-images \
- --notification-configuration "{\"LambdaFunctionConfigurations\": [{\"LambdaFunctionArn\": \"$(awslocal lambda get-function --function-name resize --output json | jq -r .Configuration.FunctionArn)\", \"Events\": [\"s3:ObjectCreated:*\"]}]}"
-```
+ **Retrieve the URL:**
-#### Create the S3 static website
+ ```bash
+ LAMBDA_URL=$(tflocal output -raw function_url)
+ echo $LAMBDA_URL
+ ```
-```bash
-awslocal s3 mb s3://webapp
-awslocal s3 sync --delete ./website s3://webapp
-awslocal s3 website s3://webapp --index-document index.html
-```
+
+
-#### Retrieve the Lambda Function URLs
+## Step 3 — Test the API
-Retrieve the Lambda function URLs for the `presign` and `list` Lambda functions using the following commands:
+Store a message:
```bash
-awslocal lambda list-function-url-configs --function-name presign --output json | jq -r '.FunctionUrlConfigs[0].FunctionUrl'
-awslocal lambda list-function-url-configs --function-name list --output json | jq -r '.FunctionUrlConfigs[0].FunctionUrl'
+curl -X POST "$LAMBDA_URL" \
+ -H "Content-Type: application/json" \
+ -d '{"message": "Hello, LocalStack!"}'
```
-Save these URLs for later use in the sample application.
-
-### Run the sample AWS application
-
-To access the application, go to [**https://webapp.s3-website.localhost.localstack.cloud:4566**](https://webapp.s3-website.localhost.localstack.cloud:4566) in your browser.
-
-
-
-Paste the `presign` and `list` Lambda function URLs into the application and click **Apply**.
-Alternatively, click on **Load from API** to automatically load the URLs.
-
-Upload an image, and click **Upload**.
-The upload form uses the `presign` Lambda to request an S3 pre-signed POST URL, forwarding the POST request to S3.
-Asynchronous resizing (maximum 400x400 pixels) occurs through S3 bucket notifications.
-
-If successful, the application displays a **success!** alert.
-Click **Refresh** to trigger your browser to request the `list` Lambda URL, returning a JSON document of all items in the images (`localstack-thumbnails-app-images`) and resized images (`localstack-thumbnails-app-resized`) bucket.
-
-
-
-### View the deployed resources
+You should get back a response like:
-You can inspect the resources deployed as part of the sample application by accessing the [**LocalStack Web Application**](https://app.localstack.cloud/).
-Navigate to your [**Default Instance**](https://app.localstack.cloud/inst/default/status) to view the deployed resources.
-
-
-
-Click on [S3](https://app.localstack.cloud/inst/default/resources/s3) or [Lambda](https://app.localstack.cloud/inst/default/resources/lambda/functions) to view the S3 buckets and Lambda functions respectively.
-
-
-
-### Run integration tests
+```json
+{ "id": "a1b2c3d4-...", "message": "Hello, LocalStack!" }
+```
-To run automated integration tests against the sample application, use the following command:
+List all messages:
```bash
-pytest -v
+curl "$LAMBDA_URL"
```
-Additionally, you can verify that when the `resize` Lambda fails, an SNS message is sent to a topic that an SES subscription listens to, triggering an email with the raw failure message.
-Since there's no real email server involved, you can use the LocalStack SES developer endpoint to list messages sent via SES:
+**That's the win.** You just invoked a real Lambda function that wrote to a real DynamoDB table — all running locally, with no AWS account and no cloud costs.
-```bash
-curl -s http://localhost.localstack.cloud:4566/_aws/ses | jq
-```
+## Step 4 — Inspect your resources
-An alternative option is to use a service like MailHog or `smtp4dev`.
-Start LocalStack with `SMTP_HOST=host.docker.internal:1025`, pointing to the mock SMTP server.
+You can browse the resources you just deployed in the [LocalStack Web Application](https://app.localstack.cloud/).
+Navigate to your [Default Instance](https://app.localstack.cloud/inst/default/status) and click through to [Lambda](https://app.localstack.cloud/inst/default/resources/lambda/functions) or [DynamoDB](https://app.localstack.cloud/inst/default/resources/dynamodb) to see your running infrastructure.
-### Destroy the local infrastructure
+## Step 5 — Clean up
-Now that you've learned how to deploy a local AWS infrastructure for your sample application, let's clean up and tear down the resources associated with the project:
+When you're done, stop LocalStack to tear down all local resources:
```bash
-localstack stop
+lstk stop # if using lstk
+localstack stop # if using the LocalStack CLI
```
-LocalStack is ephemeral, meaning it doesn't persist any data across restarts.
-It runs inside a Docker container, and once it's stopped, all locally created resources are automatically removed.
-
-To persist the local cloud resources across restarts, navigate to our [persistence documentation](/aws/capabilities/state-management/persistence) or learn about [Cloud Pods](/aws/capabilities/state-management/cloud-pods), our next generation state management utility.
-
-## Next Steps
+LocalStack is ephemeral by default — stopping it removes all provisioned resources.
+To persist state across restarts, see [Persistence](/aws/capabilities/state-management/persistence/) or [Cloud Pods](/aws/capabilities/state-management/cloud-pods/).
-Congratulations on deploying an AWS application locally using LocalStack!
-To expand your LocalStack capabilities, explore the following based on your expertise:
+## Next steps
-- [Tutorials](/aws/tutorials): Check out our tutorials to learn how to use LocalStack across various AWS services and application stacks.
-- [Supported Services](/aws/services): Explore LocalStack's emulated AWS services.
-- [Capabilities](/aws/capabilities/): Learn about LocalStack's capabilities including features like IAM policy stream, state management, and more.
-- [Tooling](/aws/tooling/): Get details on LocalStack's tooling and integrations.
-- [Blog](https://blog.localstack.cloud): Read our blog posts about LocalStack and the latest enhancements for a better local development and testing experience.
+- [Tutorials](/aws/tutorials/) — Deeper dives into specific AWS services and application stacks
+- [Supported Services](/aws/services/) — Full list of emulated AWS services
+- [CI/CD Setup](/aws/getting-started/ci-cd/) — Run LocalStack in GitHub Actions and other pipelines
+- [AI & Agent Workflows](/aws/getting-started/ai-workflows/) — Use LocalStack with AI coding tools and agents
+- [Tooling](/aws/tooling/) — `awslocal`, `tflocal`, LocalStack Desktop, and more