From b17a57b3dd5ba6783fbc6d09bf47dc1934de5085 Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Fri, 24 Apr 2026 14:06:47 -0400 Subject: [PATCH 01/14] Initial draft for revising getting started The concepts behind this draft: 1. Design paths for the main LocalStack use cases 2. Simplify the quickstart to get them to success faster 3. Have both an awslocal and a terraform quickstart 4. Bring AI and agent use cases up front [DOC-12](https://linear.app/localstack/issue/DOC-12/docs-quickstart-v2) --- .../docs/aws/getting-started/ai-workflows.mdx | 73 +++ .../docs/aws/getting-started/auth-token.mdx | 2 +- .../docs/aws/getting-started/ci-cd.mdx | 185 +++++++ src/content/docs/aws/getting-started/faq.mdx | 2 +- .../docs/aws/getting-started/help-support.md | 2 +- src/content/docs/aws/getting-started/index.md | 23 - .../docs/aws/getting-started/index.mdx | 48 ++ .../docs/aws/getting-started/installation.mdx | 85 ++- .../docs/aws/getting-started/quickstart.mdx | 501 ++++++++---------- 9 files changed, 588 insertions(+), 333 deletions(-) create mode 100644 src/content/docs/aws/getting-started/ai-workflows.mdx create mode 100644 src/content/docs/aws/getting-started/ci-cd.mdx delete mode 100644 src/content/docs/aws/getting-started/index.md create mode 100644 src/content/docs/aws/getting-started/index.mdx 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..f4444269 100644 --- a/src/content/docs/aws/getting-started/quickstart.mdx +++ b/src/content/docs/aws/getting-started/quickstart.mdx @@ -1,361 +1,294 @@ --- 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'; +import { 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: +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. -- 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. +By the end you will have: -## Architecture +- 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 -The following diagram shows the architecture that we will deploy locally using LocalStack: - -![An AWS architecture demonstrating a sample serverless image resizer application](https://user-images.githubusercontent.com/3996682/229322761-92f52eec-5bfb-412a-a3cb-8af4ee1fed24.png) - -The architecture: - -- 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. - -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` - -You can start LocalStack using the `localstack` CLI. -Start the LocalStack for AWS container with your `LOCALSTACK_AUTH_TOKEN` pre-configured: +- [Docker](https://docs.docker.com/get-docker/) installed and running +- A [LocalStack account](https://app.localstack.cloud/sign-up) (free tier works) - - - \nlocalstack start`} lang="shell" /> - - - \nlocalstack start`} lang="shell" /> - - +## Step 1 — Install and start LocalStack -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. +The fastest way to get LocalStack running locally is with `lstk`, a lightweight CLI that handles authentication and image setup automatically. -## Instructions + + + Install `lstk`: -To get started, clone the sample application repository from GitHub: + ```bash + brew install localstack/tap/lstk # macOS / Linux with Homebrew + ``` -```bash -git clone https://github.com/localstack-samples/sample-serverless-image-resizer-s3-lambda.git -cd sample-serverless-image-resizer-s3-lambda -``` + ```bash + npm install -g @localstack/lstk # or via npm + ``` -You can now follow the instructions below to start LocalStack, deploy the sample application, and test the application. + Then start LocalStack: -### Setup a virtual environment + ```bash + lstk start + ``` -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`: + On first run, `lstk` opens a browser login to authenticate, then pulls the image and starts the container automatically. - - - ```shell - python -m venv .venv - source .venv/bin/activate - pip install -r 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 - .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: +Wait for the container to report ready — you'll see a log line like `Ready.` or you can verify with: + ```bash -pyenv install 3.11 -pyenv global 3.11 +curl -s http://localhost:4566/_localstack/health | grep '"running"' ``` -::: -### Setup the serverless image resizer +## Step 2 — Deploy the serverless API -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. +Now deploy a Lambda function and a DynamoDB table. Pick the tooling you prefer: -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: + + + Install the `awslocal` wrapper if you haven't already: -```bash -deployment/build-lambdas.sh -``` + ```bash + pip install awscli-local + ``` -You can now deploy the sample application on LocalStack by running the following command: + **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 -deployment/awslocal/deploy.sh -``` + **Create the DynamoDB table:** -Alternatively, you can follow these instructions to deploy the sample application manually step-by-step. + ```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 + ``` -:::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. -::: + **Deploy the Lambda:** -#### Create the S3 buckets + ```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 s3 mb s3://localstack-thumbnails-app-images -awslocal s3 mb s3://localstack-thumbnails-app-resized -``` + awslocal lambda wait function-active --function-name messages-api + ``` -#### Add bucket names into the parameter store + **Create a public function URL:** -```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" -``` + ```bash + awslocal lambda create-function-url-config \ + --function-name messages-api \ + --auth-type NONE + ``` -#### Create SNS DLQ Topic for failed lambda invocations + **Retrieve the URL:** -```bash -awslocal sns create-topic --name failed-resize-topic -``` + ```bash + LAMBDA_URL=$(awslocal lambda list-function-url-configs \ + --function-name messages-api \ + --query 'FunctionUrlConfigs[0].FunctionUrl' \ + --output text) + echo $LAMBDA_URL + ``` + + + Install Terraform and the `tflocal` wrapper: -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: + ```bash + brew install hashicorp/tap/terraform # or see https://developer.hashicorp.com/terraform/install + pip install terraform-local + ``` -```bash -awslocal sns subscribe \ - --topic-arn arn:aws:sns:us-east-1:000000000000:failed-resize-topic \ - --protocol email \ - --notification-endpoint my-email@example.com -``` + Create a project directory and `main.tf`: -#### 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 -``` + ```bash + mkdir -p /tmp/localstack-demo && cd /tmp/localstack-demo + ``` -#### 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 -``` + ```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 + } + ``` -#### Build the Image Resizer Lambda + **Deploy:** - - - ```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 + tflocal init + tflocal apply -auto-approve ``` - - - ```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 ../.. - ``` - - - ```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 ../.. + + **Retrieve the URL:** + + ```bash + LAMBDA_URL=$(tflocal output -raw function_url) + echo $LAMBDA_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 -``` +## Step 3 — Test the API -#### Connect S3 bucket to Resizer Lambda +Store a message: ```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:*\"]}]}" +curl -X POST "$LAMBDA_URL" \ + -H "Content-Type: application/json" \ + -d '{"message": "Hello, LocalStack!"}' ``` -#### Create the S3 static website +You should get back a response like: -```bash -awslocal s3 mb s3://webapp -awslocal s3 sync --delete ./website s3://webapp -awslocal s3 website s3://webapp --index-document index.html +```json +{"id": "a1b2c3d4-...", "message": "Hello, LocalStack!"} ``` -#### Retrieve the Lambda Function URLs - -Retrieve the Lambda function URLs for the `presign` and `list` Lambda functions using the following commands: +List all messages: ```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 "$LAMBDA_URL" ``` -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. - -![Serverless image resizer application](/images/aws/serverless-image-resizer-application.png) - -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. +**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. -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. +## Step 4 — Inspect your resources -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. +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. -![Serverless image resizer application displaying a resized image](/images/aws/resized-image-sample-application.png) +## Step 5 — Clean up -### View the deployed resources - -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. - -![Status Page of the LocalStack Web Application"](/images/aws/localstack-web-application-status.png) - -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. - -![The Lambda Resource Browser Page of the LocalStack Web Application](/images/aws/localstack-web-application-lambda.png) - -### Run integration tests - -To run automated integration tests against the sample application, use the following command: - -```bash -pytest -v -``` - -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: +When you're done, stop LocalStack to tear down all local resources: ```bash -curl -s http://localhost.localstack.cloud:4566/_aws/ses | jq +lstk stop # if using lstk +localstack stop # if using the LocalStack CLI ``` -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. - -### Destroy the local infrastructure - -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: - -```bash -localstack stop -``` - -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 From 6ea3ae46d9a8888c5b222c9de5f8d359c3e2692c Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Fri, 24 Apr 2026 14:47:40 -0400 Subject: [PATCH 02/14] Update quickstart.mdx --- src/content/docs/aws/getting-started/quickstart.mdx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/content/docs/aws/getting-started/quickstart.mdx b/src/content/docs/aws/getting-started/quickstart.mdx index f4444269..687b8733 100644 --- a/src/content/docs/aws/getting-started/quickstart.mdx +++ b/src/content/docs/aws/getting-started/quickstart.mdx @@ -5,6 +5,7 @@ template: doc sidebar: order: 2 --- + import { Tabs, TabItem } from '@astrojs/starlight/components'; ## Introduction @@ -24,7 +25,7 @@ Choose your preferred deployment style below: **AWS CLI** (`awslocal`) or **Terr ## Prerequisites - [Docker](https://docs.docker.com/get-docker/) installed and running -- A [LocalStack account](https://app.localstack.cloud/sign-up) (free tier works) +- A [LocalStack account](https://app.localstack.cloud/sign-up) ## Step 1 — Install and start LocalStack @@ -54,6 +55,7 @@ The fastest way to get LocalStack running locally is with `lstk`, a lightweight `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. ::: + 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: @@ -61,6 +63,7 @@ The fastest way to get LocalStack running locally is with `lstk`, a lightweight ```bash localstack start ``` + @@ -143,6 +146,7 @@ Now deploy a Lambda function and a DynamoDB table. Pick the tooling you prefer: --output text) echo $LAMBDA_URL ``` + Install Terraform and the `tflocal` wrapper: @@ -241,6 +245,7 @@ Now deploy a Lambda function and a DynamoDB table. Pick the tooling you prefer: LAMBDA_URL=$(tflocal output -raw function_url) echo $LAMBDA_URL ``` + @@ -257,7 +262,7 @@ curl -X POST "$LAMBDA_URL" \ You should get back a response like: ```json -{"id": "a1b2c3d4-...", "message": "Hello, LocalStack!"} +{ "id": "a1b2c3d4-...", "message": "Hello, LocalStack!" } ``` List all messages: From 71369d638c82c8f76090482ccbd711ed083bc30c Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Tue, 28 Apr 2026 07:46:48 -0400 Subject: [PATCH 03/14] Clean up the ordering Fixed some issues on the quick start and reordered the pages to make a more logical order --- .../docs/aws/getting-started/ai-workflows.mdx | 10 +- .../docs/aws/getting-started/auth-token.mdx | 2 +- .../docs/aws/getting-started/ci-cd.mdx | 24 +- .../docs/aws/getting-started/installation.mdx | 118 ++++-- .../docs/aws/getting-started/quickstart.mdx | 401 ++++++++++-------- 5 files changed, 323 insertions(+), 232 deletions(-) diff --git a/src/content/docs/aws/getting-started/ai-workflows.mdx b/src/content/docs/aws/getting-started/ai-workflows.mdx index 4746e4ff..22469037 100644 --- a/src/content/docs/aws/getting-started/ai-workflows.mdx +++ b/src/content/docs/aws/getting-started/ai-workflows.mdx @@ -3,7 +3,7 @@ title: AI & Agent Workflows description: Use LocalStack with AI coding assistants, MCP servers, and agent-driven infrastructure automation. template: doc sidebar: - order: 6 + order: 5 --- ## Overview @@ -66,8 +66,8 @@ See [Tooling](/aws/tooling/) for the full list of LocalStack-aware wrappers for ## Summary -| Use case | Tool | -|---|---| +| 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` | +| 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 4f6446c0..b35141c9 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: 4 + order: 6 --- 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 index feac5951..594ffed2 100644 --- a/src/content/docs/aws/getting-started/ci-cd.mdx +++ b/src/content/docs/aws/getting-started/ci-cd.mdx @@ -1,16 +1,16 @@ --- -title: CI/CD Setup +title: CI/CD description: Run LocalStack in CI pipelines — auth tokens, Docker Compose, and GitHub Actions examples. template: doc sidebar: - order: 5 + order: 4 --- import { Tabs, TabItem } from '@astrojs/starlight/components'; ## Overview -LocalStack works great in CI environments. +LocalStack works great in CI environments, allowing your integration tests to run incredibly fast and with no cloud costs. The setup differs from local development in a few important ways: - **Use a CI Auth Token**, not your personal Developer token @@ -67,6 +67,7 @@ See the [Auth Token documentation](/aws/getting-started/auth-token/) for full de ``` 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`: @@ -99,6 +100,7 @@ See the [Auth Token documentation](/aws/getting-started/auth-token/) for full de :::note Mounting `/var/run/docker.sock` is required for Lambda emulation, which uses Docker to run function containers. ::: + Start LocalStack directly with `docker run`: @@ -116,6 +118,7 @@ See the [Auth Token documentation](/aws/getting-started/auth-token/) for full de # 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: @@ -142,6 +145,7 @@ See the [Auth Token documentation](/aws/getting-started/auth-token/) for full de ``` Set `LOCALSTACK_AUTH_TOKEN` in your CircleCI project's environment variables. + @@ -156,13 +160,13 @@ curl -s http://localhost:4566/_localstack/info | jq '.is_license_activated' ## 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 | +| | 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 diff --git a/src/content/docs/aws/getting-started/installation.mdx b/src/content/docs/aws/getting-started/installation.mdx index dcc080ab..e6239ce0 100644 --- a/src/content/docs/aws/getting-started/installation.mdx +++ b/src/content/docs/aws/getting-started/installation.mdx @@ -3,11 +3,11 @@ title: Installation description: All installation methods for LocalStack — lstk, LocalStack CLI, Docker Compose, Docker, and Helm. template: doc sidebar: - order: 3 + order: 2 --- import { Code, LinkButton, Tabs, TabItem } from '@astrojs/starlight/components'; -import { LOCALSTACK_VERSION } from "astro:env/server"; +import { LOCALSTACK_VERSION } from 'astro:env/server'; ## Local development @@ -28,17 +28,13 @@ Install `lstk`: - ```bash - brew install localstack/tap/lstk - ``` - - - ```bash - npm install -g @localstack/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`. + Download a pre-built binary for your platform from [GitHub + Releases](https://github.com/localstack/lstk/releases) and add it to your + `PATH`. @@ -70,22 +66,43 @@ For alternative methods of managing the LocalStack container, see our [alternati You can download the pre-built binary for your architecture using the link below: -x86-64 -ARM64 + + x86-64 + + + ARM64 + or use the curl commands below: For x86-64: - + For ARM64: - + Then extract the LocalStack CLI from the terminal: - +
Alternative: Homebrew on Linux @@ -95,6 +112,7 @@ If you are using [Homebrew for Linux](https://docs.brew.sh/Homebrew-on-Linux), y ```bash brew install localstack/tap/localstack-cli ``` +
@@ -112,16 +130,28 @@ brew install localstack/tap/localstack-cli You may download the binary for your architecture using the link below: -Intel (AMD64) + + Intel (AMD64) + or use the following curl command: - + Then extract the LocalStack CLI from the terminal: - + @@ -130,9 +160,16 @@ Then extract the LocalStack CLI from the terminal: You can download the pre-built binary for your architecture using the link below: -Intel (AMD64) + + Intel (AMD64) + Then extract the archive and execute the binary in Powershell. + @@ -156,8 +193,8 @@ To download a specific version of LocalStack, replace `` with the requi ```bash python3 -m pip install localstack== ``` -::: +::: :::tip[MacOS Sierra?] If you have problems with permissions in MacOS X Sierra, install with: @@ -165,6 +202,7 @@ If you have problems with permissions in MacOS X Sierra, install with: ```bash python3 -m pip install --user localstack ``` + ::: :::danger @@ -183,7 +221,6 @@ To verify that the LocalStack CLI was installed correctly, you can check the ver You are all set! - :::note To start LocalStack, you must first [set up your auth token](/aws/getting-started/auth-token). ::: @@ -200,7 +237,7 @@ localstack start # start localstack in background with -d flag / / / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/ / /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,< /_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_| - + 💻 LocalStack CLI ${LOCALSTACK_VERSION} 👤 Profile: default @@ -211,7 +248,6 @@ localstack start # start localstack in background with -d flag [12:47:15] detaching bootstrap.py:1262 ``` - ### Updating LocalStack CLI The LocalStack CLI allows you to easily update the different components of LocalStack. @@ -287,24 +323,23 @@ Docker Compose v1.9.0 and above is supported. ```yaml showshowLineNumbers services: localstack: - container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}" - image: localstack/localstack-pro # required for Pro + container_name: '${LOCALSTACK_DOCKER_NAME:-localstack-main}' + image: localstack/localstack-pro # required for Pro ports: - - "127.0.0.1:4566:4566" # LocalStack Gateway - - "127.0.0.1:4510-4559:4510-4559" # external services port range - - "127.0.0.1:443:443" # LocalStack HTTPS Gateway (Pro) + - '127.0.0.1:4566:4566' # LocalStack Gateway + - '127.0.0.1:4510-4559:4510-4559' # external services port range + - '127.0.0.1:443:443' # LocalStack HTTPS Gateway (Pro) environment: # Activate LocalStack for AWS: https://docs.localstack.cloud/getting-started/auth-token/ - - LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:?} # required for Pro + - LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:?} # required for Pro # LocalStack configuration: https://docs.localstack.cloud/references/configuration/ - DEBUG=${DEBUG:-0} - PERSISTENCE=${PERSISTENCE:-0} volumes: - - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack" - - "/var/run/docker.sock:/var/run/docker.sock" + - '${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack' + - '/var/run/docker.sock:/var/run/docker.sock' ``` - Start the container by running the following command: ```bash @@ -312,6 +347,7 @@ docker compose up ``` :::note + - This command pulls the current nightly build from the `main` branch (if you don't have the image locally) and **not** the latest supported version. If you want to use a specific version, set the appropriate LocalStack image tag at `services.localstack.image` in the `docker-compose.yml` file (for example `localstack/localstack:`). @@ -330,7 +366,7 @@ docker compose up Please consider removing it, if this functionality is needed. - To configure an Auth Token, refer to the [Auth Token](/aws/getting-started/auth-token) documentation. -::: + ::: Please note that there are a few pitfalls when configuring your stack manually via docker-compose (e.g., required container name, Docker network, volume mounts, and environment variables). We recommend using the LocalStack CLI to validate your configuration, which will print warning messages in case it detects any potential misconfigurations: @@ -366,6 +402,7 @@ docker run \ ``` :::note + - This command pulls the current nightly build from the `main` branch (if you don't have the image locally) and **not** the latest supported version. If you want to use a specific version of LocalStack, use the appropriate tag: `docker run --rm -it -p 4566:4566 -p 4510-4559:4510-4559 localstack/localstack:`. Check-out the [LocalStack releases](https://github.com/localstack/localstack/releases) to know more about specific LocalStack versions. @@ -386,7 +423,7 @@ docker run \ For instance, setting `LOCALSTACK_PERSISTENCE=1` is equivalent to `PERSISTENCE=1`. - To configure an Auth Token, refer to the [Auth Token](/aws/getting-started/auth-token) documentation. -::: + ::: ### Helm @@ -400,6 +437,7 @@ If you want to deploy LocalStack in your [Kubernetes](https://kubernetes.io) clu #### Deploy LocalStack using Helm You can deploy LocalStack in a Kubernetes cluster by running these commands: + ```bash helm repo add localstack-repo https://helm.localstack.cloud helm upgrade --install localstack localstack-repo/localstack @@ -410,6 +448,7 @@ The Helm charts are not maintained in the main repository, but in a [separate on ## What's next? Now that you have LocalStack up and running, the following resources might be useful for your next steps: + - Check out our [Quickstart guide](/aws/getting-started/quickstart) if you are a new user to get started with LocalStack quickly. - [Use the LocalStack integrations](/aws/integrations) to interact with LocalStack and other integrated tools, for example: - Use `awslocal` to use the AWS CLI against your local cloud! @@ -425,10 +464,12 @@ Now that you have LocalStack up and running, the following resources might be us #### The LocalStack CLI installation is successful, but I cannot execute `localstack` If you can successfully install LocalStack using `pip` but you cannot use it in your terminal, you most likely haven't set up your operating system's / terminal's `PATH` variable (in order to tell them where to find programs installed via `pip`). + - If you are using Windows, you can enable the `PATH` configuration when installing Python, [as described in the official docs of Python](https://docs.python.org/3/using/windows.html#finding-the-python-executable). - If you are using a MacOS or Linux operating system, please make sure that the `PATH` is correctly set up - either system wide, or in your terminal. As a workaround you can call the LocalStack CLI python module directly: + ```bash python3 -m localstack.cli.main ``` @@ -436,12 +477,15 @@ python3 -m localstack.cli.main #### The `localstack` CLI does not start the LocalStack container If you are using the `localstack` CLI to start LocalStack, but the container is not starting, please check the following: + - Uncheck the **Use kernel networking for UDP** option in Docker Desktop (**Settings** → **Resources** → **Network**) or follow the steps in our [documentation](/aws/tooling/dns-server#system-dns-configuration) to disable it. - Start LocalStack with a specific DNS address: + ```bash DNS_ADDRESS=0 localstack start ``` -- Remove port 53 as indicated in our [standard `docker-compose.yml` file](https://github.com/localstack/localstack/blob/main/docker-compose-pro.yml). + +- Remove port 53 as indicated in our [standard `docker-compose.yml` file](https://github.com/localstack/localstack/blob/main/docker-compose-pro.yml). #### How should I access the LocalStack logs on my local machine? diff --git a/src/content/docs/aws/getting-started/quickstart.mdx b/src/content/docs/aws/getting-started/quickstart.mdx index 687b8733..00f268b7 100644 --- a/src/content/docs/aws/getting-started/quickstart.mdx +++ b/src/content/docs/aws/getting-started/quickstart.mdx @@ -1,16 +1,16 @@ --- -title: Quickstart +title: Local Development description: Deploy a serverless API locally with LocalStack in under 10 minutes using Lambda and DynamoDB. template: doc sidebar: - order: 2 + order: 3 --- -import { Tabs, TabItem } from '@astrojs/starlight/components'; +import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; ## 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. +In this quickstart you'll start LocalStack and deploy a simple serverless API including a Lambda function backed by DynamoDB, entirely on your local machine. No AWS account needed. By the end you will have: @@ -18,9 +18,9 @@ By the end you will have: - 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 +- A local environment that behaves like real AWS -Choose your preferred deployment style below: **AWS CLI** (`awslocal`) or **Terraform** (`tflocal`). +Choose your preferred deployment style below: **AWS CLI** or **Terraform**. ## Prerequisites @@ -46,10 +46,19 @@ The fastest way to get LocalStack running locally is with `lstk`, a lightweight Then start LocalStack: ```bash - lstk start + lstk ``` - On first run, `lstk` opens a browser login to authenticate, then pulls the image and starts the container automatically. + On first run, `lstk` opens a browser window to authenticate. It also pulls the LocalStack image and starts the container automatically. + + When the container is ready, you'll see log lines like: + + ```bash + ✔︎ LocalStack ready (containerId: 400b3e61f3c6) + • Endpoint: localhost.localstack.cloud:4566 + • Web app: https://app.localstack.cloud + > Tip: View deployed resources: lstk status + ``` :::note[Early release] `lstk` currently supports core lifecycle commands (start, stop, logs, status). @@ -64,188 +73,213 @@ The fastest way to get LocalStack running locally is with `lstk`, a lightweight localstack start ``` - - + When the container is ready, you'll see log lines like: -Wait for the container to report ready — you'll see a log line like `Ready.` or you can verify with: + ```bash + __ _______ __ __ + / / ____ _________ _/ / ___// /_____ ______/ /__ + / / / __ \/ ___/ __ `/ /\__ \/ __/ __ `/ ___/ //_/ + / /___/ /_/ / /__/ /_/ / /___/ / /_/ /_/ / /__/ ,< + /_____/\____/\___/\__,_/_//____/\__/\__,_/\___/_/|_| + + 💻 LocalStack CLI ${LOCALSTACK_VERSION} + 👤 Profile: default + + [12:47:13] starting LocalStack in Docker mode 🐳 localstack.py:494 + preparing environment bootstrap.py:1240 + configuring container bootstrap.py:1248 + starting container bootstrap.py:1258 + [12:47:15] detaching bootstrap.py:1262 + ``` -```bash -curl -s http://localhost:4566/_localstack/health | grep '"running"' -``` + + ## Step 2 — Deploy the serverless API -Now deploy a Lambda function and a DynamoDB table. Pick the tooling you prefer: +Now deploy a Lambda function and a DynamoDB table. For this tutorial, you can choose between creating resources using the AWS CLI via our `awslocal` wrapper or Terraform via our `tflocal` wrapper. - Install the `awslocal` wrapper if you haven't already: - - ```bash - pip install awscli-local - ``` - - **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 - ``` - - **Create the DynamoDB table:** - - ```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 - ``` - - **Deploy the Lambda:** - - ```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} - - awslocal lambda wait function-active --function-name messages-api - ``` - - **Create a public function URL:** - - ```bash - awslocal lambda create-function-url-config \ - --function-name messages-api \ - --auth-type NONE - ``` - - **Retrieve the URL:** - - ```bash - LAMBDA_URL=$(awslocal lambda list-function-url-configs \ - --function-name messages-api \ - --query 'FunctionUrlConfigs[0].FunctionUrl' \ - --output text) - echo $LAMBDA_URL - ``` + + +1. Install the `awslocal` wrapper if you haven't already: + + ```bash + pip install awscli-local + ``` + +2. Create the Lambda function + + The below code creates a Lambda function using Python and zips the code to be ready for deployment. + + ```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 + ``` + +3. Create the DynamoDB table + + ```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 + ``` + +4. Deploy the Lambda + + ```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} + + awslocal lambda wait function-active --function-name messages-api + ``` + +5. Create a public function URL + + ```bash + awslocal lambda create-function-url-config \ + --function-name messages-api \ + --auth-type NONE + ``` + +6. Retrieve the URL + + ```bash + LAMBDA_URL=$(awslocal lambda list-function-url-configs \ + --function-name messages-api \ + --query 'FunctionUrlConfigs[0].FunctionUrl' \ + --output text) + echo $LAMBDA_URL + ``` + + - Install Terraform and the `tflocal` wrapper: + +1. Install Terraform and the `tflocal` wrapper: ```bash - brew install hashicorp/tap/terraform # or see https://developer.hashicorp.com/terraform/install + brew install hashicorp/tap/terraform pip install terraform-local ``` - Create a project directory and `main.tf`: - - ```bash - mkdir -p /tmp/localstack-demo && cd /tmp/localstack-demo - ``` - - ```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 - } - ``` - - **Deploy:** - - ```bash - tflocal init - tflocal apply -auto-approve - ``` - - **Retrieve the URL:** - - ```bash - LAMBDA_URL=$(tflocal output -raw function_url) - echo $LAMBDA_URL - ``` - + For additional installation options, see the [Terraform installation guide](https://developer.hashicorp.com/terraform/install). + +2. Create a project directory. + + ```bash + mkdir -p /tmp/localstack-demo && cd /tmp/localstack-demo + ``` + + Then create a `main.tf` file with the following content: + + ```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 + } + ``` + +3. Deploy + + ```bash + tflocal init + tflocal apply -auto-approve + ``` + +4. Retrieve the URL + + ```bash + LAMBDA_URL=$(tflocal output -raw function_url) + echo $LAMBDA_URL + ``` + + @@ -280,16 +314,25 @@ Navigate to your [Default Instance](https://app.localstack.cloud/inst/default/st ## Step 5 — Clean up -When you're done, stop LocalStack to tear down all local resources: +First, stop LocalStack to tear down all local resources: -```bash -lstk stop # if using lstk -localstack stop # if using the LocalStack CLI -``` +{/* prettier-ignore-start */} + + + ```bash lstk stop ``` + ```bash localstack stop ``` + +{/* prettier-ignore-end */} 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/). +Now that you're done, you can remove the tutorial files from your machine (the Lambda source, zip, and, if you used Terraform, `main.tf` and state under the same folder): + +```bash +rm -rf /tmp/localstack-demo +``` + ## Next steps - [Tutorials](/aws/tutorials/) — Deeper dives into specific AWS services and application stacks From c778969deee249c6a1712a0cfca17e5ed992c105 Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Tue, 28 Apr 2026 08:45:42 -0400 Subject: [PATCH 04/14] Clean up CI-CD landing page --- .../docs/aws/getting-started/ci-cd.mdx | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/content/docs/aws/getting-started/ci-cd.mdx b/src/content/docs/aws/getting-started/ci-cd.mdx index 594ffed2..0618d865 100644 --- a/src/content/docs/aws/getting-started/ci-cd.mdx +++ b/src/content/docs/aws/getting-started/ci-cd.mdx @@ -1,6 +1,6 @@ --- title: CI/CD -description: Run LocalStack in CI pipelines — auth tokens, Docker Compose, and GitHub Actions examples. +description: Run LocalStack in CI pipelines — auth tokens, Docker Compose, GitHub Actions examples, and persisting state with Cloud Pods or state export. template: doc sidebar: order: 4 @@ -11,15 +11,16 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; ## Overview LocalStack works great in CI environments, allowing your integration tests to run incredibly fast and with no cloud costs. -The setup differs from local development in a few important ways: +The setup differs slighty 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 +- **Runs are often isolated per job** — many pipelines start from an empty LocalStack instance for reproducible tests +- **Persistence in CI is supported** — [Cloud Pods](/aws/capabilities/state-management/cloud-pods/), snapshot-based [persistence](/aws/capabilities/state-management/persistence/) with a mounted volume, or `localstack state export` / `localstack state import` with artifacts or cache. ## 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. +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** @@ -52,9 +53,10 @@ See the [Auth Token documentation](/aws/getting-started/auth-token/) for full de - uses: actions/checkout@v4 - name: Start LocalStack - uses: LocalStack/setup-localstack@v0.2 + uses: LocalStack/setup-localstack@v0.2.2 with: image-tag: latest + install-awslocal: "true" env: LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }} @@ -160,20 +162,24 @@ curl -s http://localhost:4566/_localstack/info | jq '.is_license_activated' ## 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 | +| | 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 | Optional persistence (same mechanisms; typical pattern is a fresh instance per job) | +| **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 tear down the container at the end of a job, nothing is left on disk unless you save it — which is why many teams use a clean instance every time. +When you **do** need to reuse infrastructure or data between pipeline runs or steps, CI is fully supported: -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. +- **[Cloud Pods](/aws/capabilities/state-management/cloud-pods/)** — save and load snapshots; the [`setup-localstack`](https://github.com/localstack/setup-localstack) action can load and save pods via `state-backend: cloud-pods` (see [GitHub Actions](/aws/integrations/continuous-integration/github-actions/) — _Store Localstack state_). +- **Snapshot-based [persistence](/aws/capabilities/state-management/persistence/)** — enable `PERSISTENCE=1` and mount a volume so state survives container restarts on the same runner or workspace. +- **State export/import** — run `localstack state export` and `localstack state import` and pass the file through your CI provider’s **artifacts**, **cache**, or attached storage (for example, see [GitLab CI](/aws/integrations/continuous-integration/gitlab-ci/) — _Store Localstack state_). + +Choose the approach that fits your runner model: for example, multi-job GitLab pipelines often need explicit state handoff because services do not carry between jobs. ## More CI integrations From 9ed0787d20584084592370047d08a8aef8f569fe Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Tue, 28 Apr 2026 16:01:01 -0400 Subject: [PATCH 05/14] Improvements to the AI page --- .../docs/aws/getting-started/ai-workflows.mdx | 66 ++++++++++++------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/src/content/docs/aws/getting-started/ai-workflows.mdx b/src/content/docs/aws/getting-started/ai-workflows.mdx index 22469037..7ab8e76e 100644 --- a/src/content/docs/aws/getting-started/ai-workflows.mdx +++ b/src/content/docs/aws/getting-started/ai-workflows.mdx @@ -8,39 +8,61 @@ sidebar: ## 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. +AI-assisted development workflows need a fast and secure environment to develop and test in. +Whether you're using an AI coding assistant to generate infrastructure code, running an agent that deploys AWS resources, or validating AI-generated IaC before applying it to real AWS — LocalStack gives you a safe, fast, cost-free environment to run these workflows 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. +The [LocalStack MCP Server](https://github.com/localstack/localstack-mcp-server) is a [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server that connects compatible clients (Claude, Cursor, Windsurf, and others) to your LocalStack environment. +It gives agents tools to run the full local cloud lifecycle—not only generating infrastructure code, but starting the container, deploying and tearing down IaC, analyzing logs, and more. +See [Introducing the LocalStack MCP Server](https://blog.localstack.cloud/introducing-localstack-mcp-server/) for the original announcement and walkthrough. -With the MCP server connected, your AI assistant can: +With the MCP server configured, your assistant can use tools such as: -- 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 +- **Lifecycle** — Start, stop, restart, or check status of the LocalStack container +- **Deploy** — Deploy or destroy CDK, Terraform, SAM, or CloudFormation projects on LocalStack +- **Operations** — Analyze logs, run AWS CLI commands via `awslocal`, manage [Cloud Pods](/aws/capabilities/state-management/cloud-pods/), and (where supported) IAM policy analysis, chaos injection, and docs search -**Quick setup:** +...and many more. -```bash -# Install the LocalStack MCP server -pip install localstack-mcp-server +### MCP Server Prerequisites + +Before you begin, make sure these are installed and in your system's `PATH`: + +- [Node.js](https://nodejs.org/en/) (v20.x or later) to run the `npx` command. +- [LocalStack CLI](https://docs.localstack.cloud/user-guide/cli/) and [Docker](https://docs.docker.com/get-docker/) to manage the LocalStack container itself. +- [`cdklocal`](https://docs.localstack.cloud/user-guide/integrations/aws-cdk/) or [`tflocal`](https://docs.localstack.cloud/user-guide/integrations/terraform/) to use the `localstack-deployer` tool. (optional) +- A [LocalStack Auth Token](https://docs.localstack.cloud/getting-started/auth-token/) to enable licensed features. (optional) + +### MCP Server Configuration + +Add a server entry like this to your client's MCP configuration—for **Cursor**, this would typically be `~/.cursor/mcp.json`. +For **Claude Code**, register the server with `claude mcp add` (it is saved to your project-level MCP configuration).. + +```json +{ + "mcpServers": { + "localstack-mcp-server": { + "command": "npx", + "args": ["-y", "@localstack/localstack-mcp-server"], + "env": { + "LOCALSTACK_AUTH_TOKEN": "" + } + } + } +} ``` -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. +Full prerequisites, Cursor/VS Code/Claude Code variants, custom endpoints (`LOCALSTACK_HOSTNAME`, `LOCALSTACK_PORT`), troubleshooting, and the complete tool reference are on [LocalStack MCP Server](/aws/tooling/mcp-server/). :::note -The MCP server connects to a running LocalStack instance — make sure LocalStack is started first with `lstk start` or `localstack start`. +You do not need to start LocalStack manually before using MCP: an agent can start the container using the **localstack-management** tool once this configuration is in place. +If LocalStack already runs elsewhere, point the MCP server at it via the `env` block as described in [Connecting to a custom LocalStack endpoint](/aws/tooling/mcp-server/#connecting-to-a-custom-localstack-endpoint). ::: ## 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: @@ -66,8 +88,8 @@ See [Tooling](/aws/tooling/) for the full list of LocalStack-aware wrappers for ## 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` | +| Use case | Tool | +| ------------------------------------------------------ | --------------------------------------------------------- | +| AI assistant that can inspect & manage local resources | [LocalStack MCP Server](/aws/tooling/mcp-server/) | +| Agent-driven infrastructure deployment | [LocalStack Skills](https://github.com/localstack/skills) | +| Validate AI-generated IaC safely | LocalStack + `tflocal` / `cdklocal` / `awslocal` | From 0b1b0dd941021516d802ff0f65daeb0098d2e1bb Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Tue, 28 Apr 2026 16:39:00 -0400 Subject: [PATCH 06/14] Minor improvement to the AI page --- src/content/docs/aws/getting-started/ai-workflows.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/aws/getting-started/ai-workflows.mdx b/src/content/docs/aws/getting-started/ai-workflows.mdx index 7ab8e76e..51efca9d 100644 --- a/src/content/docs/aws/getting-started/ai-workflows.mdx +++ b/src/content/docs/aws/getting-started/ai-workflows.mdx @@ -37,7 +37,7 @@ Before you begin, make sure these are installed and in your system's `PATH`: ### MCP Server Configuration Add a server entry like this to your client's MCP configuration—for **Cursor**, this would typically be `~/.cursor/mcp.json`. -For **Claude Code**, register the server with `claude mcp add` (it is saved to your project-level MCP configuration).. +For **Claude Code**, register the server with `claude mcp add` (it is saved to your project-level MCP configuration). ```json { @@ -62,7 +62,7 @@ If LocalStack already runs elsewhere, point the MCP server at it via the `env` b ## 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. +[LocalStack Skills](https://github.com/localstack/skills) are pre-built agent skill definitions for deploying common AWS architectures locally. It contains skills for LocalStack lifecycle management, IaC deployment, state management and more. Skills can be used in combination with the MCP server to create a fully autonomous agent-driven workflow. Skills are useful when: From b73231c79c2353a720fe71e1b56b601f4af27e0b Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Tue, 28 Apr 2026 17:05:26 -0400 Subject: [PATCH 07/14] Some reworking of the intro and removal of outdated content --- .../docs/aws/getting-started/auth-token.mdx | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/content/docs/aws/getting-started/auth-token.mdx b/src/content/docs/aws/getting-started/auth-token.mdx index b35141c9..aea872ca 100644 --- a/src/content/docs/aws/getting-started/auth-token.mdx +++ b/src/content/docs/aws/getting-started/auth-token.mdx @@ -10,10 +10,16 @@ import { Code, Tabs, TabItem } from '@astrojs/starlight/components'; ## Introduction -The Auth Token is required to activate the LocalStack for AWS core cloud emulator. It identifies and authenticates users outside the LocalStack Web Application. -It primarily accesses your workspace and advanced services & features. +The Auth Token activates LocalStack for AWS. It ties the running instance to your workspace and license and is required whenever you use LocalStack for AWS. -Auth tokens come in two types: a **Developer Auth Token** and a **CI Auth Token**: +**Whether you need to configure a token by hand** depends on how you run LocalStack: + +- **[`lstk`](/aws/tooling/lstk)** (early release) — For most local development, the Auth Token is present but easy to overlook. On first run or after `lstk login`, the CLI completes a browser login flow, stores your **Developer Auth Token** in the system keyring (or a config-directory fallback when no keyring is available), and injects it into the container whenever you start LocalStack. You are still using an Auth Token for activation; `lstk` obtains and reuses it after login instead of asking you to set `LOCALSTACK_AUTH_TOKEN` yourself. +- **LocalStack CLI (`localstack`)** — You configure the token yourself: set `LOCALSTACK_AUTH_TOKEN` or run `localstack auth set-token` (see [Configuring your Auth Token](#configuring-your-auth-token)). [`lstk`](/aws/tooling/lstk) is currently in early release and missing some core features, so the `localstack` CLI is still the right tool for Cloud Pods, Extensions, Ephemeral Instances, and other advanced features, so many workflows keep using it and therefore set an Auth Token explicitly. For personal development, use your **Developer Auth Token** from the web app. +- **Docker or Docker Compose** — You pass `LOCALSTACK_AUTH_TOKEN` into the container (see [Configuring your Auth Token](#configuring-your-auth-token)). Use your **Developer Auth Token** for local runs unless you are in CI. +- **CI pipelines and other automated, non-interactive environments** — You must set `LOCALSTACK_AUTH_TOKEN` to a **CI Auth Token**. Developer Auth Tokens should not be used in CI. See [CI Environments](#ci-environments). + +Auth tokens come in two types: a **Developer Auth Token** and a **CI Auth Token**. - The **Developer Auth Token** is linked to a specific user within a specific workspace. Every user has their own Auth Token. @@ -205,25 +211,6 @@ Another way to confirm this is by checking the logs of the LocalStack container Otherwise, check our [troubleshooting](#troubleshooting) section. -## FAQ - -### How do I activate older versions of LocalStack (Before v3.0)? - -Prior to the introduction of Auth Tokens, LocalStack used **API keys** managed through the `LOCALSTACK_API_KEY` environment variable for activation. - -For backwards compatibility, we've updated our back-end to accept new Auth Tokens within the `LOCALSTACK_API_KEY` variable. -You can use the new Auth Token in the same way you previously used the API key. - -### When will the legacy API keys be phased out? - -In early 2025, we will begin phasing out legacy API keys entirely. -After the sunsetting period, legacy API and legacy CI keys will no longer activate or work with LocalStack. - -During the sunsetting period, the legacy service will experience scheduled downtimes. -These are planned to encourage users to transition to new Auth Tokens while minimizing impact for those who have not yet updated. - -The downtime schedule will be communicated well in advance, allowing users ample time to switch to the new Auth Tokens. - ## Troubleshooting While using Auth Tokens, LocalStack demands a successful license activation for startup. From 72d35ca63f433ed4cfee6cab96593dff17bb3665 Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Tue, 28 Apr 2026 17:19:01 -0400 Subject: [PATCH 08/14] Added kubernetes as a secondary path This was per the suggestion of Colin --- src/components/SecondaryPathCard.tsx | 20 ++++++++++++++++ .../docs/aws/getting-started/index.mdx | 11 +++++++++ src/styles/global.css | 24 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 src/components/SecondaryPathCard.tsx diff --git a/src/components/SecondaryPathCard.tsx b/src/components/SecondaryPathCard.tsx new file mode 100644 index 00000000..39aaf79c --- /dev/null +++ b/src/components/SecondaryPathCard.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +interface SecondaryPathCardProps { + title: string; + href: string; + children: React.ReactNode; +} + +export const SecondaryPathCard: React.FC = ({ title, href, children }) => { + return ( + + ); +}; diff --git a/src/content/docs/aws/getting-started/index.mdx b/src/content/docs/aws/getting-started/index.mdx index 4b0e2503..a948b454 100644 --- a/src/content/docs/aws/getting-started/index.mdx +++ b/src/content/docs/aws/getting-started/index.mdx @@ -8,6 +8,7 @@ sidebar: --- import { SectionCards } from '../../../../components/SectionCards.tsx'; +import { SecondaryPathCard } from '../../../../components/SecondaryPathCard.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. @@ -46,3 +47,13 @@ LocalStack for AWS also includes advanced capabilities for teams: [Cloud Pods](/ ]} client:load /> + + + +LocalStack for AWS supports **running inside a Kubernetes cluster** (for example with the Operator or Helm chart), that is an **Enterprise-only** deployment model enabling dynamic scaling, isolation, and native Kubernetes orchestration. + + diff --git a/src/styles/global.css b/src/styles/global.css index c00c4feb..33e14b98 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -108,6 +108,30 @@ h3 { transform: translateY(-2px); } +.path-secondary-card { + margin-top: 1rem; +} + +.path-secondary-card .path-secondary-card__title { + font-size: 18px; + font-weight: 500; + letter-spacing: -0.12px; +} + +.path-secondary-card .path-secondary-card__body { + font-size: 16px; + line-height: 26px; + color: var(--sl-color-gray-3); +} + +.path-secondary-card .path-secondary-card__body > :first-child { + margin-top: 0; +} + +.path-secondary-card .path-secondary-card__body > :last-child { + margin-bottom: 0; +} + .service-box-content { height: 100%; display: flex; From bb1cc26f96ef5e223d238399d726d43aace8b455 Mon Sep 17 00:00:00 2001 From: Brian Rinaldi Date: Wed, 29 Apr 2026 07:38:07 -0400 Subject: [PATCH 09/14] Modify to note lstk for CI --- src/content/docs/aws/getting-started/ci-cd.mdx | 16 ++++++++-------- .../docs/aws/getting-started/installation.mdx | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/content/docs/aws/getting-started/ci-cd.mdx b/src/content/docs/aws/getting-started/ci-cd.mdx index 0618d865..ced79a3e 100644 --- a/src/content/docs/aws/getting-started/ci-cd.mdx +++ b/src/content/docs/aws/getting-started/ci-cd.mdx @@ -14,7 +14,7 @@ LocalStack works great in CI environments, allowing your integration tests to ru The setup differs slighty 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 +- **Start LocalStack without a browser** — Docker Compose, `docker run`, or CI helpers such as [`setup-localstack`](https://github.com/localstack/setup-localstack) are common; [`lstk`](/aws/tooling/lstk/) also works in CI when you set `LOCALSTACK_AUTH_TOKEN` and use [`--non-interactive`](/aws/tooling/lstk/#interactive-and-non-interactive-mode) (or rely on automatic non-interactive detection). LocalStack Desktop remains a local-only GUI. - **Runs are often isolated per job** — many pipelines start from an empty LocalStack instance for reproducible tests - **Persistence in CI is supported** — [Cloud Pods](/aws/capabilities/state-management/cloud-pods/), snapshot-based [persistence](/aws/capabilities/state-management/persistence/) with a mounted volume, or `localstack state export` / `localstack state import` with artifacts or cache. @@ -162,13 +162,13 @@ curl -s http://localhost:4566/_localstack/info | jq '.is_license_activated' ## 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 | Optional persistence (same mechanisms; typical pattern is a fresh instance per job) | -| **Startup** | Interactive TUI | `--non-interactive` / `-d` flag | +| | Local development | CI/CD | +| -------------- | -------------------------------- | ----------------------------------------------------------------------------------- | +| **CLI** | `lstk` or LocalStack CLI | Docker Compose / `docker run`, or `lstk --non-interactive` | +| **Auth** | Browser login or stored token | `LOCALSTACK_AUTH_TOKEN` env var | +| **Token type** | Developer token | CI token | +| **State** | Optional persistence | Optional persistence (same mechanisms; typical pattern is a fresh instance per job) | +| **Startup** | Interactive TUI (default `lstk`) | Non-interactive (`docker compose`, `docker run -d`, `lstk --non-interactive`) | ## Persisting state across runs diff --git a/src/content/docs/aws/getting-started/installation.mdx b/src/content/docs/aws/getting-started/installation.mdx index d6096189..2fc40200 100644 --- a/src/content/docs/aws/getting-started/installation.mdx +++ b/src/content/docs/aws/getting-started/installation.mdx @@ -278,7 +278,7 @@ If it was installed using the pre-built binary or via Brew, please run the insta ## CI and server environments -For CI pipelines and server deployments, you'll manage the LocalStack container directly rather than using a local CLI. +For CI pipelines and server deployments, use non-interactive startup: Docker Compose or `docker run` are typical, or [`lstk --non-interactive`](/aws/tooling/lstk/#interactive-and-non-interactive-mode) with `LOCALSTACK_AUTH_TOKEN`. See the [CI/CD Setup guide](/aws/getting-started/ci-cd/) for a complete walkthrough including GitHub Actions examples. The options below cover the main container management approaches: From 6ef84e4ab0ac11766e12f866549a8649a242013d Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 28 May 2026 22:21:32 +0200 Subject: [PATCH 10/14] Update and rename quickstart.mdx to local-development.mdx --- .../getting-started/{quickstart.mdx => local-development.mdx} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/content/docs/aws/getting-started/{quickstart.mdx => local-development.mdx} (98%) diff --git a/src/content/docs/aws/getting-started/quickstart.mdx b/src/content/docs/aws/getting-started/local-development.mdx similarity index 98% rename from src/content/docs/aws/getting-started/quickstart.mdx rename to src/content/docs/aws/getting-started/local-development.mdx index 00f268b7..8855f590 100644 --- a/src/content/docs/aws/getting-started/quickstart.mdx +++ b/src/content/docs/aws/getting-started/local-development.mdx @@ -10,7 +10,7 @@ import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; ## Introduction -In this quickstart you'll start LocalStack and deploy a simple serverless API including a Lambda function backed by DynamoDB, entirely on your local machine. +In this guide you'll start LocalStack and deploy a simple serverless API including a Lambda function backed by DynamoDB, entirely on your local machine. No AWS account needed. By the end you will have: From b7ebb19049ccbcf2120470cc4e297daa961045e1 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 28 May 2026 22:30:49 +0200 Subject: [PATCH 11/14] Draft 2: rewrite index.mdx --- .../docs/aws/getting-started/index.mdx | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/content/docs/aws/getting-started/index.mdx b/src/content/docs/aws/getting-started/index.mdx index a948b454..a639c333 100644 --- a/src/content/docs/aws/getting-started/index.mdx +++ b/src/content/docs/aws/getting-started/index.mdx @@ -1,6 +1,6 @@ --- 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. +description: Introduction to LocalStack for AWS, covering core use cases, local cloud capabilities, and deployment options for development and testing. template: doc editUrl: false sidebar: @@ -8,52 +8,44 @@ sidebar: --- import { SectionCards } from '../../../../components/SectionCards.tsx'; -import { SecondaryPathCard } from '../../../../components/SecondaryPathCard.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. +LocalStack provides a cloud service emulator that runs within a single container on your local machine or CI environment. It delivers a functional AWS environment including Lambda, DynamoDB, S3, SQS, and [80+ supported services](/aws/services/), enabling development and testing without an AWS account or cloud-related costs. -Here's why developers and teams use it: +### Core Use Cases -- **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. +- **Accelerate development loops**: Test changes against local AWS services instantly to bypass deployment wait times. +- **Automate integration testing**: Execute integration tests against local AWS infrastructure within pull requests to identify regressions before production. +- **Validate IaC**: Deploy Terraform, CDK, or CloudFormation templates to LocalStack to verify infrastructure logic before applying changes to a cloud environment. +- **Experimental sandbox**: Explore new AWS services and architectures in a risk-free environment. -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. +LocalStack also provides advanced features for team collaboration and security, including [Cloud Pods](/aws/capabilities/state-management/cloud-pods/) for state management, [IAM policy enforcement](/aws/capabilities/security-testing/iam-policy-enforcement/), and [Chaos Engineering](/aws/capabilities/chaos-engineering/). -## Choose your path +## Explore by deployment - - -LocalStack for AWS supports **running inside a Kubernetes cluster** (for example with the Operator or Helm chart), that is an **Enterprise-only** deployment model enabling dynamic scaling, isolation, and native Kubernetes orchestration. - - +:::note +**Enterprise K8 Deployment:** LocalStack also supports execution within Kubernetes clusters via the Operator or Helm charts. This model enables dynamic scaling, environment isolation, and native orchestration. See our [Kubernetes Deployment guide](/aws/enterprise/kubernetes/) for more information. +::: From fb4ec712bd60f1cbfc5f110d85a63aad67ca8a41 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 28 May 2026 22:32:39 +0200 Subject: [PATCH 12/14] Delete dead code: src/components/SecondaryPathCard.tsx The reference to the k8 tutorial has been moved into a standard Note component. This file is now dead code. --- src/components/SecondaryPathCard.tsx | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/components/SecondaryPathCard.tsx diff --git a/src/components/SecondaryPathCard.tsx b/src/components/SecondaryPathCard.tsx deleted file mode 100644 index 39aaf79c..00000000 --- a/src/components/SecondaryPathCard.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; - -interface SecondaryPathCardProps { - title: string; - href: string; - children: React.ReactNode; -} - -export const SecondaryPathCard: React.FC = ({ title, href, children }) => { - return ( - - ); -}; From deede21ff5f8e7ba41ba7c3775ed2ddb42f55b67 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 28 May 2026 23:09:22 +0200 Subject: [PATCH 13/14] Draft 2: installation.mdx Removed redundant "Next Steps" clutter and relocated Docker, Compose, and Helm to a dedicated orchestration section. Standardized tone and corrected tool categorizations. --- .../docs/aws/getting-started/installation.mdx | 377 +++--------------- 1 file changed, 66 insertions(+), 311 deletions(-) diff --git a/src/content/docs/aws/getting-started/installation.mdx b/src/content/docs/aws/getting-started/installation.mdx index 2fc40200..8e792cef 100644 --- a/src/content/docs/aws/getting-started/installation.mdx +++ b/src/content/docs/aws/getting-started/installation.mdx @@ -1,6 +1,6 @@ --- title: Installation -description: All installation methods for LocalStack — lstk, LocalStack CLI, Docker Compose, Docker, and Helm. +description: Installation guides for LocalStack CLIs, container engines, and orchestration tools. template: doc sidebar: order: 2 @@ -9,211 +9,79 @@ sidebar: import { Code, LinkButton, Tabs, TabItem } from '@astrojs/starlight/components'; import { LOCALSTACK_VERSION } from 'astro:env/server'; -## Local development +LocalStack provides multiple installation paths depending on your development environment and requirements. We recommend using a CLI-based installation for the most consistent local development experience. -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. +Choose the CLI that fits your workflow: use [`lstk`](#lstk) for a streamlined, non-Python setup, or [LocalStack CLI](#localstack-cli) for access to our complete feature set. -### lstk +## 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. +`lstk` is a lightweight, Go-based binary that manages the authentication and container lifecycle in a single workflow. -:::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. +:::caution[Early Release] +`lstk` currently supports core lifecycle commands: `start`, `stop`, `logs`, and `status`. For advanced features like Cloud Pods or Extensions, use the [LocalStack CLI](#localstack-cli). ::: -Install `lstk`: +**Install lstk** - - ```bash brew install localstack/tap/lstk ``` + + ```bash + brew install localstack/tap/lstk + ``` + + + ```bash + npm install -g @localstack/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`. + Download the binary for your platform from the [GitHub Releases](https://github.com/localstack/lstk/releases) and add it to your `PATH`. -Start LocalStack: +**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](#ci-and-server-environments). - - - - - -You can download the pre-built binary for your architecture using the link below: +``` - - x86-64 - - - ARM64 - +The first execution initiates a browser-based login flow. Subsequent starts use credentials stored in your system keyring. -or use the curl commands below: -For x86-64: +## LocalStack CLI - +The LocalStack CLI is the primary tool for managing all LocalStack capabilities. -For ARM64: +**Requirement:** You must have a working [Docker installation](https://docs.docker.com/get-docker/) before proceeding. - +### Install LocalStack CLI -Then extract the LocalStack CLI from the terminal: +x86-64 +ARM64 - +Extract the binary to `/usr/local/bin`: -
-Alternative: Homebrew on Linux + -If you are using [Homebrew for Linux](https://docs.brew.sh/Homebrew-on-Linux), you can install the LocalStack CLI directly from our official LocalStack tap: ```bash brew install localstack/tap/localstack-cli -``` -
- -
- - - -You can install the LocalStack CLI using Brew directly from our official LocalStack tap: - -```bash -brew install localstack/tap/localstack-cli ``` -
-Alternative: Binary Download - -You may download the binary for your architecture using the link below: - - - Intel (AMD64) - - -or use the following curl command: - - - -Then extract the LocalStack CLI from the terminal: - - - -
-
- - - -You can download the pre-built binary for your architecture using the link below: - - - Intel (AMD64) - - -Then extract the archive and execute the binary in Powershell. - - - - - -If you cannot use the binary releases of LocalStack, you can install the Python distribution. - -Please make sure to install the following before moving ahead: - -- [Python](https://docs.python.org/3/using/index.html) -- [pip](https://pip.pypa.io/en/stable/installation/) - -Next install the LocalStack CLI in your Python environment by running: - ```bash python3 -m pip install --upgrade localstack -``` - -:::note -To download a specific version of LocalStack, replace `` with the required version from [release page](https://github.com/localstack/localstack/releases). -```bash -python3 -m pip install localstack== -``` - -::: - -:::tip[MacOS Sierra?] -If you have problems with permissions in MacOS X Sierra, install with: - -```bash -python3 -m pip install --user localstack ``` -::: - :::danger -Do not use `sudo` or the `root` user when starting LocalStack. -It should be installed and started entirely under a local non-root user. +Do not use `sudo` or the `root` user. Install and execute LocalStack entirely under a local non-root user. ::: - -
-### Starting LocalStack + +### Start LocalStack CLI To verify that the LocalStack CLI was installed correctly, you can check the version in your terminal: @@ -248,7 +116,7 @@ localstack start # start localstack in background with -d flag [12:47:15] detaching bootstrap.py:1262 ``` -### Updating LocalStack CLI +### Update LocalStack CLI The LocalStack CLI allows you to easily update the different components of LocalStack. To check the various options available for updating, run: @@ -276,188 +144,70 @@ 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. ::: -## CI and server environments - -For CI pipelines and server deployments, use non-interactive startup: Docker Compose or `docker run` are typical, or [`lstk --non-interactive`](/aws/tooling/lstk/#interactive-and-non-interactive-mode) with `LOCALSTACK_AUTH_TOKEN`. -See the [CI/CD Setup guide](/aws/getting-started/ci-cd/) for a complete walkthrough including GitHub Actions examples. - -The options below cover the main container management approaches: -- [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 +## Container & Orchestration Methods -The LocalStack emulator is available on Docker Hub as `localstack/localstack-pro`. +Use these methods for CI pipelines, server environments, or manual container management. -For a comprehensive overview of LocalStack images, see the [Docker images documentation](/aws/capabilities/config/docker-images). +### Docker Compose -## GUI tools +Recommended for CI and team environments. Create a `docker-compose.yml` with the following configuration: -- [LocalStack Desktop](#localstack-desktop) — desktop UI for managing your local instance -- [LocalStack Docker Extension](#localstack-docker-extension) — manage LocalStack from Docker Desktop - -### LocalStack Desktop - -Learn more about our desktop client at [LocalStack Desktop](/aws/capabilities/web-app/localstack-desktop) and download it [here](https://app.localstack.cloud/download). - -### LocalStack Docker Extension - -Install our [official Docker Desktop extension](https://hub.docker.com/extensions/localstack/localstack-docker-desktop) to manage LocalStack. -See [LocalStack Docker Extension](/aws/tooling/localstack-docker-extension) for more information. - -### Docker-Compose - -To use LocalStack without the [LocalStack CLI](#localstack-cli), you have the option of running the LocalStack Docker container by yourself. -If you want to manually manage your Docker container, it's usually a good idea to use [Docker Compose](https://docs.docker.com/compose/reference/) in order to simplify your container configuration. - -#### Prerequisites - -- [Docker](https://docs.docker.com/get-docker/) -- [Docker Compose](https://docs.docker.com/compose/install/) (version 1.9.0+) - -#### Starting LocalStack with Docker-Compose - -You can start LocalStack with [Docker Compose](https://docs.docker.com/compose/) by configuring a `docker-compose.yml` file. -Docker Compose v1.9.0 and above is supported. - -```yaml showshowLineNumbers +```yaml services: localstack: - container_name: '${LOCALSTACK_DOCKER_NAME:-localstack-main}' - image: localstack/localstack-pro # required for Pro + container_name: "${LOCALSTACK_DOCKER_NAME:-localstack-main}" + image: localstack/localstack-pro ports: - - '127.0.0.1:4566:4566' # LocalStack Gateway - - '127.0.0.1:4510-4559:4510-4559' # external services port range - - '127.0.0.1:443:443' # LocalStack HTTPS Gateway (Pro) + - "127.0.0.1:4566:4566" # Gateway + - "127.0.0.1:4510-4559:4510-4559" # External service range environment: - # Activate LocalStack for AWS: https://docs.localstack.cloud/getting-started/auth-token/ - - LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:?} # required for Pro - # LocalStack configuration: https://docs.localstack.cloud/references/configuration/ - - DEBUG=${DEBUG:-0} + - LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:?} - PERSISTENCE=${PERSISTENCE:-0} volumes: - - '${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack' - - '/var/run/docker.sock:/var/run/docker.sock' -``` - -Start the container by running the following command: + - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack" + - "/var/run/docker.sock:/var/run/docker.sock" -```bash -docker compose up ``` -:::note - -- This command pulls the current nightly build from the `main` branch (if you don't have the image locally) and **not** the latest supported version. - If you want to use a specific version, set the appropriate LocalStack image tag at `services.localstack.image` in the `docker-compose.yml` file (for example `localstack/localstack:`). - -- If you are using LocalStack with an [Auth Token](/aws/getting-started/auth-token), you need to specify the image tag as `localstack/localstack-pro` in the `docker-compose.yml` file. - Going forward, `localstack/localstack-pro` image will contain our Pro-supported services and APIs. - -- This command reuses the image if it's already on your machine, i.e. it will **not** pull the latest image automatically from Docker Hub. - -- Mounting the Docker socket `/var/run/docker.sock` as a volume is required for some services that use Docker to provide the emulation, such as AWS Lambda. - Check out the [Lambda providers](/aws/services/lambda) documentation for more information. - -- To facilitate interoperability, configuration variables can be prefixed with `LOCALSTACK_` in docker. - For instance, setting `LOCALSTACK_PERSISTENCE=1` is equivalent to `PERSISTENCE=1`. +Execute `docker compose up` to start. -- If using the Docker default bridge network using `network_mode: bridge`, container name resolution will not work inside your containers. - Please consider removing it, if this functionality is needed. +### Docker CLI -- To configure an Auth Token, refer to the [Auth Token](/aws/getting-started/auth-token) documentation. - ::: - -Please note that there are a few pitfalls when configuring your stack manually via docker-compose (e.g., required container name, Docker network, volume mounts, and environment variables). -We recommend using the LocalStack CLI to validate your configuration, which will print warning messages in case it detects any potential misconfigurations: - -```bash -localstack config validate -``` - -### Docker - -You can also directly start the LocalStack container using the Docker CLI instead of [Docker-Compose](#docker-compose). -This method requires more manual steps and configuration, but it gives you more control over the container settings. - -#### Prerequisites - -Please make sure that you have a working [Docker installation](https://docs.docker.com/get-docker/) on your machine before moving on. -You can check if Docker is correctly configured on your machine by executing `docker info` in your terminal. -If it does not report an error (but shows information on your Docker system), you're good to go. - -#### Starting LocalStack with Docker - -You can start the Docker container simply by executing the following `docker run` command: +Run the container directly via the Docker engine: ```bash docker run \ --rm -it \ -p 127.0.0.1:4566:4566 \ -p 127.0.0.1:4510-4559:4510-4559 \ - -p 127.0.0.1:443:443 \ - -e LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:?} \ -v /var/run/docker.sock:/var/run/docker.sock \ + -e LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN:?} \ localstack/localstack-pro -``` - -:::note - -- This command pulls the current nightly build from the `main` branch (if you don't have the image locally) and **not** the latest supported version. - If you want to use a specific version of LocalStack, use the appropriate tag: `docker run --rm -it -p 4566:4566 -p 4510-4559:4510-4559 localstack/localstack:`. - Check-out the [LocalStack releases](https://github.com/localstack/localstack/releases) to know more about specific LocalStack versions. - -- If you are using LocalStack with an [Auth Token](/aws/getting-started/auth-token), you need to specify the image tag as `localstack/localstack-pro` in your Docker setup. - Going forward, `localstack/localstack-pro` image will contain our Pro-supported services and APIs. - -- This command reuses the image if it's already on your machine, i.e. it will **not** pull the latest image automatically from Docker Hub. - -- Mounting the Docker socket `/var/run/docker.sock` as a volume is required for some services that use Docker to provide the emulation, such as AWS Lambda. - Check out the [Lambda providers](/aws/services/lambda) documentation for more information. -- When using Docker to manually start LocalStack, you will have to configure the container on your own (see [docker-compose-pro.yml](https://github.com/localstack/localstack/blob/main/docker-compose-pro.yml) and [Configuration](/aws/capabilities/config/configuration). - This could be seen as the "expert mode" of starting LocalStack. - If you are looking for a simpler method of starting LocalStack, please use the [LocalStack CLI](#localstack-cli). +``` -- To facilitate interoperability, configuration variables can be prefixed with `LOCALSTACK_` in docker. - For instance, setting `LOCALSTACK_PERSISTENCE=1` is equivalent to `PERSISTENCE=1`. +### Helm (Kubernetes) -- To configure an Auth Token, refer to the [Auth Token](/aws/getting-started/auth-token) documentation. - ::: +Deploy LocalStack to a Kubernetes cluster: -### Helm +```bash +helm repo add localstack-repo [https://helm.localstack.cloud](https://helm.localstack.cloud) +helm upgrade --install localstack localstack-repo/localstack -If you want to deploy LocalStack in your [Kubernetes](https://kubernetes.io) cluster, you can use [Helm](https://helm.sh). +``` -#### Prerequisites +## Graphical User Interfaces (GUIs) -- [Kubernetes](https://kubernetes.io) -- [Helm](https://helm.sh/docs/intro/install/) +### LocalStack Desktop -#### Deploy LocalStack using Helm +Manage local instances via a standalone desktop application. [Download here](https://app.localstack.cloud/download). -You can deploy LocalStack in a Kubernetes cluster by running these commands: +### Docker Desktop Extension -```bash -helm repo add localstack-repo https://helm.localstack.cloud -helm upgrade --install localstack localstack-repo/localstack -``` - -The Helm charts are not maintained in the main repository, but in a [separate one](https://github.com/localstack/helm-charts). - -## What's next? +Install the [official extension](https://hub.docker.com/extensions/localstack/localstack-docker-desktop) to manage LocalStack directly from the Docker Desktop dashboard. -Now that you have LocalStack up and running, the following resources might be useful for your next steps: -- Check out our [Quickstart guide](/aws/getting-started/quickstart) if you are a new user to get started with LocalStack quickly. -- [Use the LocalStack integrations](/aws/integrations) to interact with LocalStack and other integrated tools, for example: - - Use `awslocal` to use the AWS CLI against your local cloud! - - Use the Serverless Framework with LocalStack! - - And many more! -- [Find out how to configure LocalStack](/aws/capabilities/config/configuration) such that it perfectly fits your need. -- [Use LocalStack in your CI environment](/aws/integrations/continuous-integration/) to increase your code quality. -- [Checkout LocalStack's Cloud Developer Tools](/aws/tooling/) to further increase your development efficiency with LocalStack. -- Find out about the ways you can [configure LocalStack](/aws/capabilities/config/configuration). ## Troubleshooting @@ -529,3 +279,8 @@ After running the task, run the diagnostic endpoint and share the archive file w We have extensive network troubleshooting documentation available [here](/aws/capabilities/networking/). If this does not solve your problem then please [reach out to LocalStack Support](/aws/help-support/get-help/). + + +## Next steps + +Now that you've completed installation, proceed to the [Local Development Guide](/aws/getting-started/local-development) to start LocalStack and deploy a serverless API. This guide walks you through deploying a Lambda function backed by a DynamoDB table entirely on your local machine. From 525c3fb444311bd0810c2399720d92deffad3654 Mon Sep 17 00:00:00 2001 From: Quetzalli Date: Thu, 28 May 2026 23:44:32 +0200 Subject: [PATCH 14/14] Draft 2: local-development.mdx --- .../aws/getting-started/local-development.mdx | 425 ++++++++---------- 1 file changed, 199 insertions(+), 226 deletions(-) diff --git a/src/content/docs/aws/getting-started/local-development.mdx b/src/content/docs/aws/getting-started/local-development.mdx index 8855f590..bb8ca588 100644 --- a/src/content/docs/aws/getting-started/local-development.mdx +++ b/src/content/docs/aws/getting-started/local-development.mdx @@ -1,6 +1,6 @@ --- title: Local Development -description: Deploy a serverless API locally with LocalStack in under 10 minutes using Lambda and DynamoDB. +description: Deploy a serverless application locally using Lambda and DynamoDB on LocalStack. template: doc sidebar: order: 3 @@ -10,70 +10,62 @@ import { Tabs, TabItem, Steps } from '@astrojs/starlight/components'; ## Introduction -In this guide you'll start LocalStack and deploy a simple serverless API including a Lambda function backed by DynamoDB, entirely on your local machine. -No AWS account needed. +This guide walks you through starting LocalStack and deploying a serverless API consisting of a Lambda function and a DynamoDB table. You will perform the entire deployment on your local machine without an AWS account. -By the end you will have: +A successful deployment results in a: +- **LocalStack Container:** Running the core emulation engine. +- **Serverless API:** A Lambda function with a configured Function URL. +- **Persistence Layer:** A DynamoDB table for message storage. +- **Local Cloud Environment:** A functional AWS-emulated sandbox. -- LocalStack running locally in Docker -- A Lambda function deployed and invokable via a public URL -- A DynamoDB table storing data written by the Lambda -- A local environment that behaves like real AWS - -Choose your preferred deployment style below: **AWS CLI** or **Terraform**. +Select your preferred deployment method to begin: **AWS CLI** or **Terraform**. ## Prerequisites -- [Docker](https://docs.docker.com/get-docker/) installed and running -- A [LocalStack account](https://app.localstack.cloud/sign-up) +- [Docker](https://docs.docker.com/get-docker/) engine installed and active. +- A [LocalStack account](https://app.localstack.cloud/sign-up). -## Step 1 — Install and start LocalStack +## Step 1: Install and Start LocalStack -The fastest way to get LocalStack running locally is with `lstk`, a lightweight CLI that handles authentication and image setup automatically. +The `lstk` CLI provides the fastest initialization path by automating authentication and image management. - + Install `lstk`: ```bash - brew install localstack/tap/lstk # macOS / Linux with Homebrew + brew install localstack/tap/lstk ``` - ```bash - npm install -g @localstack/lstk # or via npm - ``` - - Then start LocalStack: + Start LocalStack: ```bash - lstk + lstk start ``` - On first run, `lstk` opens a browser window to authenticate. It also pulls the LocalStack image and starts the container automatically. + The first run triggers a browser-based authentication flow. After authentication, the CLI pulls the LocalStack image and initializes the container. - When the container is ready, you'll see log lines like: + When the container is ready, you will see the following logs: - ```bash + ```text ✔︎ LocalStack ready (containerId: 400b3e61f3c6) • Endpoint: localhost.localstack.cloud:4566 - • Web app: https://app.localstack.cloud - > Tip: View deployed resources: lstk status + • Web app: [https://app.localstack.cloud](https://app.localstack.cloud) ``` - :::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. + :::note[Early Release] + `lstk` currently supports core lifecycle commands (start, stop, logs, status). For advanced features such as Cloud Pods or Extensions, use the [LocalStack CLI](/aws/getting-started/installation/#localstack-cli). ::: - 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: + If you are using the full-featured LocalStack CLI, ensure you have [configured your auth token](/aws/getting-started/auth-token/) before starting: ```bash localstack start ``` - - When the container is ready, you'll see log lines like: + + When the container is ready, you'll see these log lines: ```bash __ _______ __ __ @@ -95,226 +87,210 @@ The fastest way to get LocalStack running locally is with `lstk`, a lightweight -## Step 2 — Deploy the serverless API +## Step 2: Deploy serverless API -Now deploy a Lambda function and a DynamoDB table. For this tutorial, you can choose between creating resources using the AWS CLI via our `awslocal` wrapper or Terraform via our `tflocal` wrapper. +Deploy the Lambda function and DynamoDB table using either the `awslocal` or `tflocal` wrappers. These tools automatically route commands to your local instance instead of AWS. -1. Install the `awslocal` wrapper if you haven't already: - - ```bash - pip install awscli-local - ``` - -2. Create the Lambda function - - The below code creates a Lambda function using Python and zips the code to be ready for deployment. - - ```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 - ``` - -3. Create the DynamoDB table - - ```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 - ``` - -4. Deploy the Lambda - - ```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} - - awslocal lambda wait function-active --function-name messages-api - ``` - -5. Create a public function URL - - ```bash - awslocal lambda create-function-url-config \ - --function-name messages-api \ - --auth-type NONE - ``` - -6. Retrieve the URL - - ```bash - LAMBDA_URL=$(awslocal lambda list-function-url-configs \ - --function-name messages-api \ - --query 'FunctionUrlConfigs[0].FunctionUrl' \ - --output text) - echo $LAMBDA_URL - ``` - - - + 1. Install the `awslocal` wrapper: + + ```bash + pip install awscli-local + ``` + + 2. Create the Lambda function source. + Execute the following to create a project directory and a Python handler: + + ```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 + ``` + + 3. Create the DynamoDB table: + + ```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 + ``` + + 4. Deploy the Lambda function: + + ```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} + + awslocal lambda wait function-active --function-name messages-api + ``` + + 5. Configure a public URL and retrieve the endpoint: + + ```bash + awslocal lambda create-function-url-config \ + --function-name messages-api \ + --auth-type NONE + + LAMBDA_URL=$(awslocal lambda list-function-url-configs \ + --function-name messages-api \ + --query 'FunctionUrlConfigs[0].FunctionUrl' \ + --output text) + echo $LAMBDA_URL + ``` + + -1. Install Terraform and the `tflocal` wrapper: - - ```bash - brew install hashicorp/tap/terraform - pip install terraform-local - ``` - - For additional installation options, see the [Terraform installation guide](https://developer.hashicorp.com/terraform/install). - -2. Create a project directory. - - ```bash - mkdir -p /tmp/localstack-demo && cd /tmp/localstack-demo - ``` - - Then create a `main.tf` file with the following content: - - ```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 - } - ``` - -3. Deploy - - ```bash - tflocal init - tflocal apply -auto-approve - ``` - -4. Retrieve the URL - - ```bash - LAMBDA_URL=$(tflocal output -raw function_url) - echo $LAMBDA_URL - ``` - - + 1. Install Terraform and the `tflocal` wrapper: + + ```bash + pip install terraform-local + ``` + + 2. Create a `main.tf` file in a new directory: + + ```hcl + 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 + } + ``` + + 3. Initialize and apply the configuration: + + ```bash + tflocal init && tflocal apply -auto-approve + ``` + + 4. Retrieve the endpoint: + + ```bash + LAMBDA_URL=$(tflocal output -raw function_url) + echo $LAMBDA_URL + ``` + -## Step 3 — Test the API +## Step 3: Test the API -Store a message: +Send a POST request to store a message in the emulated DynamoDB table: ```bash curl -X POST "$LAMBDA_URL" \ -H "Content-Type: application/json" \ -d '{"message": "Hello, LocalStack!"}' + ``` -You should get back a response like: +You will get back a response: ```json { "id": "a1b2c3d4-...", "message": "Hello, LocalStack!" } ``` -List all messages: +Retrieve all your messages: ```bash curl "$LAMBDA_URL" + ``` -**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. +The Lambda function executes within the local environment and interacts with the emulated DynamoDB service. Because no actual cloud resources are created, you won't incur any cloud costs or infrastructure changes. -## Step 4 — Inspect your resources +## Step 4: Inspect Resources -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. +View the state of your local infrastructure via the [LocalStack Web Application](https://app.localstack.cloud/). +Navigate to the [Resource Browser](https://app.localstack.cloud/inst/default/status) to inspect your Lambda functions and DynamoDB tables in real-time. -## Step 5 — Clean up +## Step 5: Clean Up -First, stop LocalStack to tear down all local resources: +Stop your LocalStack container to remove all emulated resources. LocalStack is ephemeral by default; stopping the instance clears the state. {/* prettier-ignore-start */} @@ -324,19 +300,16 @@ First, stop LocalStack to tear down all local resources: {/* prettier-ignore-end */} -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/). -Now that you're done, you can remove the tutorial files from your machine (the Lambda source, zip, and, if you used Terraform, `main.tf` and state under the same folder): +Remove the local files you created in this guide: ```bash rm -rf /tmp/localstack-demo + ``` ## Next steps -- [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 +You have successfully deployed and tested a serverless API on your local workstation. Proceed to the [CI/CD guide](/aws/getting-started/ci-cd/) to learn how to integrate LocalStack into your automated testing pipelines and GitHub Actions workflows. +