diff --git a/README.md b/README.md
index fbab1f2e7..bf8a3b95f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
# LocalStack Docs v2
+
This is just the Starlight starter for now. We can begin moving existing content into `/content/docs`.
## Starlight Starter Kit: Basics
diff --git a/astro.config.mjs b/astro.config.mjs
index 806385428..1b91f906b 100644
--- a/astro.config.mjs
+++ b/astro.config.mjs
@@ -629,10 +629,6 @@ export default defineConfig({
label: 'LocalStack Docker Extension',
slug: 'aws/configuration/localstack-docker-extension',
},
- {
- label: 'LocalSurf',
- slug: 'aws/configuration/localsurf',
- },
],
},
{
diff --git a/public/_redirects b/public/_redirects
index 2fcbfbf92..f626cd01c 100644
--- a/public/_redirects
+++ b/public/_redirects
@@ -122,7 +122,7 @@
/references/coverage/coverage_es/ /aws/services/es 301
/user-guide/integrations/sdks/javascript/ /aws/connecting/aws-sdks/net/javascript 301
/references/coverage/coverage_iam/ /aws/services/iam 301
-/user-guide/tools/localsurf/ /aws/configuration/localsurf 301
+/user-guide/tools/localsurf/ /aws/customization/networking/ 301
/user-guide/extensions/extensions-library/ /aws/configuration/extensions/extensions-library 301
/tutorials/ecs-ecr-container-app/ /aws/tutorials/ecs-ecr-container-app 301
/references/coverage/coverage_elastictranscoder/ /aws/services/elastictranscoder 301
@@ -529,7 +529,7 @@
/references/coverage/coverage_es /aws/services/es 301
/user-guide/integrations/sdks/javascript /aws/connecting/aws-sdks/net/javascript 301
/references/coverage/coverage_iam /aws/services/iam 301
-/user-guide/tools/localsurf /aws/configuration/localsurf 301
+/user-guide/tools/localsurf /aws/customization/networking/ 301
/user-guide/extensions/extensions-library /aws/configuration/extensions/extensions-library 301
/tutorials/ecs-ecr-container-app /aws/tutorials/ecs-ecr-container-app 301
/references/coverage/coverage_elastictranscoder /aws/services/elastictranscoder 301
@@ -944,8 +944,8 @@
/aws/tooling/testing-utils/ /aws/configuration/testing-utils 301
/aws/tooling/localstack-docker-extension /aws/configuration/localstack-docker-extension 301
/aws/tooling/localstack-docker-extension/ /aws/configuration/localstack-docker-extension 301
-/aws/tooling/localsurf /aws/configuration/localsurf 301
-/aws/tooling/localsurf/ /aws/configuration/localsurf 301
+/aws/tooling/localsurf /aws/customization/networking/ 301
+/aws/tooling/localsurf/ /aws/customization/networking/ 301
/aws/tooling /aws/developer-tools 301
/aws/tooling/ /aws/developer-tools/ 301
@@ -999,8 +999,8 @@
/aws/capabilities/localstack-sdks/java-sdk/ /aws/configuration/localstack-sdks/java-sdk 301
/aws/capabilities/localstack-sdks/python-sdk /aws/configuration/localstack-sdks/python-sdk 301
/aws/capabilities/localstack-sdks/python-sdk/ /aws/configuration/localstack-sdks/python-sdk 301
-/aws/capabilities/localsurf /aws/configuration/localsurf 301
-/aws/capabilities/localsurf/ /aws/configuration/localsurf 301
+/aws/capabilities/localsurf /aws/customization/networking/ 301
+/aws/capabilities/localsurf/ /aws/customization/networking/ 301
/aws/capabilities/networking /aws/configuration/networking 301
/aws/capabilities/networking/ /aws/configuration/networking 301
/aws/capabilities/networking/accessing-endpoint-url /aws/configuration/networking/accessing-endpoint-url 301
diff --git a/scripts/redirects/_redirects b/scripts/redirects/_redirects
index da10a1531..213b5ab6c 100644
--- a/scripts/redirects/_redirects
+++ b/scripts/redirects/_redirects
@@ -121,7 +121,7 @@
/references/coverage/coverage_es/ /aws/services/es 301
/user-guide/integrations/sdks/javascript/ /aws/integrations/aws-sdks/net/javascript 301
/references/coverage/coverage_iam/ /aws/services/iam 301
-/user-guide/tools/localsurf/ /aws/tooling/localsurf 301
+/user-guide/tools/localsurf/ /aws/customization/networking/ 301
/user-guide/extensions/extensions-library/ /aws/tooling/extensions/extensions-library 301
/tutorials/ecs-ecr-container-app/ /aws/tutorials/ecs-ecr-container-app 301
/references/coverage/coverage_elastictranscoder/ /aws/services/elastictranscoder 301
diff --git a/scripts/redirects/redirects_config.json b/scripts/redirects/redirects_config.json
index 6f3580563..50ccf6902 100644
--- a/scripts/redirects/redirects_config.json
+++ b/scripts/redirects/redirects_config.json
@@ -612,7 +612,7 @@
},
{
"old_link": "/user-guide/tools/localsurf/",
- "new_link": "/aws/tooling/localsurf",
+ "new_link": "/aws/customization/networking",
"status_code": 301
},
{
diff --git a/src/content/docs/aws/configuration/config/configuration.md b/src/content/docs/aws/configuration/config/configuration.md
index 9ad76f33d..f63006b15 100644
--- a/src/content/docs/aws/configuration/config/configuration.md
+++ b/src/content/docs/aws/configuration/config/configuration.md
@@ -197,14 +197,20 @@ This section covers configuration options that are specific to certain AWS servi
| Variable | Example Values | Description |
| - | - | - |
-| `EKS_K3S_FLAGS` | | Customize the `k3s` cluster created by LocalStack to emulate EKS clusters. |
+| `K3S_FLAGS` | | Customize the `k3s` cluster created by LocalStack to emulate EKS clusters. (formerly `EKS_K3S_FLAGS`, still accepted as a deprecated alias) |
| `EKS_LOADBALANCER_PORT` | `8081` (default) | Local port on which the Kubernetes load balancer is exposed on the host. |
-| `EKS_K3S_IMAGE_TAG` | `v1.31.5-k3s1` (default) | Custom tag of the `rancher/k3s` image used to spin up Kubernetes clusters locally. |
-| `EKS_K8S_PROVIDER` | `k3s` (default)\|`local` | The k8s provider which should be used to start the k8s cluster backing EKS. For more information on the providers, please see [Elastic Kubernetes Service (EKS)](/aws/services/eks) |
-| `EKS_K3S_IMAGE_REPOSITORY` | `rancher/k3s` (default) | Custom repository of the `rancher/k3s` image used to spin up Kubernetes clusters locally. |
-| `EKS_START_K3D_LB_INGRESS` | `0` (default) | Whether to start the k3d load balancer and Traefik ingress controller automatically when creating an EKS cluster. Set to `1` to enable. |
+| `K3S_IMAGE_TAG` | `v1.31.5-k3s1` (default) | Custom tag of the `rancher/k3s` image used to spin up Kubernetes clusters locally. (formerly `EKS_K3S_IMAGE_TAG`, still accepted as a deprecated alias) |
+| `MANAGED_K8S_PROVIDER` | `k3s` (default)\|`local` | The k8s provider which should be used to start the k8s cluster backing EKS. For more information on the providers, please see [Elastic Kubernetes Service (EKS)](/aws/services/eks) (formerly `EKS_K8S_PROVIDER`, still accepted as a deprecated alias) |
+| `K3S_IMAGE_REPOSITORY` | `rancher/k3s` (default) | Custom repository of the `rancher/k3s` image used to spin up Kubernetes clusters locally. (formerly `EKS_K3S_IMAGE_REPOSITORY`, still accepted as a deprecated alias) |
+| `K3D_START_LB_INGRESS` | `0` (default) | Whether to start the k3d load balancer and Traefik ingress controller automatically when creating an EKS cluster. Set to `1` to enable. (formerly `EKS_START_K3D_LB_INGRESS`, still accepted as a deprecated alias) |
| `EKS_PERSIST_CLUSTER_CONTENTS` | `0` (default) | When Persistence is enabled or when saving/loading Cloud Pods, this flag can be used to control whether the content deployed to EKS clusters will be persisted. Set to `1` to enable. |
-| `EKS_K3D_CLUSTER_TOKEN` | `localstack-k3d-cluster-token` (default) | Token used to authenticate agent nodes joining a k3d-backed EKS cluster. Setting an explicit token ensures consistent node authentication across k3d versions, which is required for dynamic agent assignment. Can be overridden via the `EKS_K3D_CLUSTER_TOKEN` environment variable. |
+| `K3D_CLUSTER_TOKEN` | `localstack-k3d-cluster-token` (default) | Token used to authenticate agent nodes joining a k3d-backed EKS cluster. Setting an explicit token ensures consistent node authentication across k3d versions, which is required for dynamic agent assignment. (formerly `EKS_K3D_CLUSTER_TOKEN`, still accepted as a deprecated alias) |
+
+:::note
+The EKS configuration variables were renamed to cloud-agnostic names since they're shared across cloud emulators (AWS EKS / Azure AKS). The previous `EKS_*`, `LOCALSTACK_K8S_*`, and `LAMBDA_K8S_*` names still work as deprecated aliases and will be removed in a future release.
+
+If you configure these options through the LocalStack CLI **v1**, keep the `LOCALSTACK_` prefix on the new names (e.g. `LOCALSTACK_MANAGED_K8S_PROVIDER`). The CLI v1 only forwards host environment variables prefixed with `LOCALSTACK_` into the container, where the prefix is stripped to yield the in-container variable (`MANAGED_K8S_PROVIDER`).
+:::
### ElastiCache
@@ -462,7 +468,6 @@ To learn more about these configuration options, see [DNS Server](/aws/configura
| Variable | Example Values | Description |
|----------------------|----------------|-------------|
-| `ACTIVATE_PRO` | `0` \| `1` (default) | Whether Pro should be activated or not. This is set to true by default if using the `localstack/localstack-pro` container image. If set to `1`, LocalStack will fail to start if the license key activation did not work. If set to `0`, an attempt is made to start LocalStack without Pro features. |
| `LOCALSTACK_AUTH_TOKEN` | | [Auth token](/aws/getting-started/auth-token) to activate LocalStack for AWS. |
| `LOCALSTACK_API_KEY` | | **Deprecated since 3.0.0** API key to activate LocalStack for AWS.
**Use the `LOCALSTACK_AUTH_TOKEN` instead (except for [CI environments](/aws/integrations/continuous-integration/)).** |
| `LOG_LICENSE_ISSUES` | `0` \| `1` (default) | Whether to log issues with the license activation to the console. |
diff --git a/src/content/docs/aws/configuration/index.mdx b/src/content/docs/aws/configuration/index.mdx
index ed3684e56..fb77458eb 100644
--- a/src/content/docs/aws/configuration/index.mdx
+++ b/src/content/docs/aws/configuration/index.mdx
@@ -13,7 +13,7 @@ LocalStack provides a number of configuration options and supporting tools that
It brings together the configuration options that control LocalStack's behavior, networking setup for reaching your services, the LocalStack Web App, the LocalStack SDKs for programmatic access, and the extensions mechanism for adding new functionality.
-You will also find guides for several standalone tools: the [DNS Server](/aws/configuration/dns-server), [Testing Utils](/aws/configuration/testing-utils), the [LocalStack Docker Extension](/aws/configuration/localstack-docker-extension), and [LocalSurf](/aws/configuration/localsurf).
+You will also find guides for several standalone tools: the [DNS Server](/aws/configuration/dns-server), [Testing Utils](/aws/configuration/testing-utils), and the [LocalStack Docker Extension](/aws/configuration/localstack-docker-extension).
This plugin is experimental and still under active development.
-> Please report any issues or feature requests on our [GitHub repository](https://github.com/localstack/local-surf).
-
-## Installation
-
-This extension is not yet available in the Chrome Web Store, but can be installed directly from source.
-Clone the repository on your local machine to get started:
-
-```bash
-git clone git@github.com:localstack/local-surf.git
-```
-
-Head over to `chrome://extensions/` in Chrome, then select `"Load unpacked"` and point to the directory where the source code files are stored on the disk.
-
-Once installed, a new icon should appear in the Chrome extensions bar.
-When clicking on the icon, the plugin can be enabled/disabled by toggling the **Enable local mode** checkbox.
-
-
-
-
-## Usage
-
-To illustrate how the plugin works, we use the AWS [Serverlesspresso](https://github.com/aws-samples/serverless-coffee-workshop) sample application.
-This app consists of various backend components (e.g., DynamoDB tables, Lambda functions, Cognito user pools, etc), as well as a hosted Web app user interface (UI) that can be used to interact with the backend components.
-
-We can deploy the backend components to LocalStack directly, using the `samlocal` command line interface (CLI):
-
-```bash
-samlocal build
-samlocal deploy
-```
-
-Once deployed, the `samlocal` CLI will print out a display app URL which will look similar to the following:
-
-```bash
-Key DisplayAppURI
-Description The URL for the Display App
-Value https://workshop-display.serverlesscoffee.com/?region=us-east-1&userPoolId=us-east-1_43c9800e64c84467aa0abdb102e226ef&userPoolWebClientId=vr9aw2jr7iv36ezwaaqlzzkvbp&poolId=us-east-1:95dc88d0-1029-48fe-ba7b-1e6a9741bfc5&host=localhost.localstack.cloud&orderManagerEndpoint=https://fapencq0ue.execute-api.amazonaws.com:4566/Prod&APIGWEndpointValidatorService=https://psmdc7b1lv.execute-api.amazonaws.com:4566/Prod&APIGWEndpointConfigService=https://hw7yw61ba7.execute-api.amazonaws.com:4566/Prod
-```
-
-We can then open the URL in the browser and confirm the configurations in the form dialog:
-
-
-
-Once confirmed, we are being forwarded to a signin screen, which uses an AWS Cognito user pool to manage authentication:
-
-
-
-After clicking **Sign In** in this form, we can see that the browser makes a request to LocalStack (to `localhost.localstack.cloud`, which is a domain name that resolves to `127.0.0.1`).
-
-
-
-This sample demonstrates how we can take an existing Web application, without any modification, and make it talk to the LocalStack APIs directly from the browser via the LocalSurf plugin.
-
-## Note
-
-Use this extension at your own risk - it is provided on an as-is basis, **without** warranties or conditions of **any** kind.
-In particular, it is your obligation to ensure that the use of this extension is compliant with the user license agreement and the terms & conditions of Amazon Web Services (AWS) and their services.
\ No newline at end of file
diff --git a/src/content/docs/aws/developer-tools/app-inspector/index.md b/src/content/docs/aws/developer-tools/app-inspector/index.md
index e3f5cd5fb..60138e601 100644
--- a/src/content/docs/aws/developer-tools/app-inspector/index.md
+++ b/src/content/docs/aws/developer-tools/app-inspector/index.md
@@ -64,6 +64,8 @@ The interface enables you to trace the flow of operations, identify relationship

+Use the search box above the operations list to filter by any text fragment, such as a resource name, an ARN segment, a status message, or a payload snippet. Search is case-insensitive, matches substrings anywhere in the field, and covers the full result set rather than just the operations currently loaded on screen.
+
### Graph View and Operation Details
Click **View Detail** to visualize the relationships between AWS services in your application as an interactive graph. Each node represents a service, and each edge represents a call between them, making it easy to follow the path of a request across your architecture.
diff --git a/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx b/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx
index 9e04183cf..0c4829da1 100644
--- a/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx
+++ b/src/content/docs/aws/developer-tools/running-localstack/lstk.mdx
@@ -15,13 +15,10 @@ import { Tabs, TabItem } from '@astrojs/starlight/components';
It provides a built-in terminal UI (TUI) for interactive use and plain text output for CI/CD pipelines and scripting.
`lstk` handles the full emulator lifecycle: authentication, pulling the Docker image, starting, stopping, and restarting the container, streaming logs, and checking status.
-It can also save and load emulator state — as local snapshots or Cloud Pods — reset running state, run AWS CLI commands against the emulator, and manage the on-disk volume.
+It can also save and load emulator state — as local snapshots, Cloud Pods, or in your own S3 bucket — reset running state, and manage the on-disk volume.
+It proxies your existing tooling — the AWS and Azure CLIs, Terraform, AWS CDK, and the AWS SAM CLI — so they run directly against LocalStack.
Running `lstk` with no arguments takes you through the entire startup flow automatically.
-:::note
-`lstk` supports core lifecycle commands (`start`, `stop`, `restart`, `logs`, `status`) along with state management via snapshots (`snapshot save`/`snapshot load`, `reset`) and an AWS CLI proxy (`lstk aws`).
-:::
-
## Prerequisites
- [Docker](https://docs.docker.com/get-docker/) installed and running.
@@ -175,7 +172,10 @@ The default `config.toml` created on first run:
type = "aws" # Emulator type. Supported: "aws", "snowflake", "azure"
tag = "latest" # Docker image tag, e.g. "latest", "2026.4"
port = "4566" # Host port the emulator will be accessible on
+# image = "" # Override the default Docker image (internal registry mirror or offline image)
# volume = "" # Host directory for persistent state (default: OS cache dir)
+# volumes = [] # Docker-style "host:container[:ro]" bind mounts (see below)
+# snapshot = "" # Snapshot REF auto-loaded after the AWS emulator starts (e.g. "pod:my-baseline")
# env = [] # Named environment profiles to apply (see [env.*] sections below)
```
@@ -186,7 +186,10 @@ port = "4566" # Host port the emulator will be accessible on
| `type` | string | `"aws"` | Emulator type. One of `"aws"`, `"snowflake"`, `"azure"`. Run a single `[[containers]]` block at a time. See [Emulator types](#emulator-types). |
| `tag` | string | `"latest"` | Docker image tag (`"latest"`, `"2026.4"`, etc.). Useful for pinning a specific version. Zero-padded months (`"2026.04"`) are normalized to `"2026.4"`. |
| `port` | string | `"4566"` | Host port the emulator listens on (1–65535). The in-container port is always `4566`. |
-| `volume` | string | (OS cache) | Host directory for persistent emulator state. Defaults to `/lstk/volume/`. |
+| `image` | string | (unset) | Override the default Docker image, e.g. an internal-registry mirror or a locally loaded offline image. If it already carries a tag, `tag` is dropped; otherwise `tag` (or `latest`) is appended. When unset, the default `localstack/` image is used. |
+| `volume` | string | (OS cache) | Host directory for persistent emulator state (mounted at `/var/lib/localstack`). Defaults to `/lstk/volume/`. Used verbatim (no path resolution). |
+| `volumes`| string[] | `[]` | Docker-style `"host:container[:ro]"` bind mounts (e.g. Snowflake init hooks). May also carry the persistence mount (the entry targeting `/var/lib/localstack`); relative host sources are resolved against the config file's directory and a leading `~/` is expanded. See [Volume mounts](#volume-mounts). |
+| `snapshot` | string | (unset) | Snapshot `REF` (a `pod:`, local path, or `s3://` location) auto-loaded after the AWS emulator starts. See [Auto-loading a snapshot on start](#auto-loading-a-snapshot-on-start). |
| `env` | string[] | `[]` | List of named environment profiles to inject into the container (see below). |
:::note
@@ -211,7 +214,9 @@ On the first interactive run, `lstk` prompts you to pick an emulator (`a` for AW
In non-interactive mode the default `aws` emulator is used.
Lifecycle commands operate on the emulators defined in your `config.toml`.
-Run a single `[[containers]]` block at a time; the AWS-specific commands (`status` resources, `aws`, `snapshot`, `reset`, `setup aws`) require an `aws` emulator to be configured.
+Run a single `[[containers]]` block at a time.
+The AWS-specific commands — the resources listing in `status`, `reset`, the `aws` CLI proxy, the IaC proxies (`terraform`, `cdk`, `sam`), and `setup aws` — require an `aws` emulator; `az` and `setup azure` require an `azure` emulator.
+`snapshot` (`save`/`load`/`list`/`remove`/`show`) works with any emulator, though some snapshot features are fully supported only on the AWS emulator for now — see the snapshot docs for your emulator for details.
:::note
The AWS emulator's license is validated by `lstk` before the container starts.
@@ -250,6 +255,32 @@ If you reference an `env` profile name that doesn't exist in your config, `lstk`
In addition to your custom profiles, `lstk` always injects several variables into the container.
See [Container-injected variables](#container-injected-variables) for the full list.
+### Volume mounts
+
+Each `[[containers]]` block accepts a `volumes` list of Docker-style `"host:container[:ro]"` bind specs, in addition to the singular `volume` field.
+This is useful for mounting initialization hooks (scripts run at the container lifecycle stages under `/etc/localstack/init/{boot,start,ready,shutdown}.d`) or any other host path into the emulator.
+
+The example below uses `volumes` to map multiple mounts — a `ready`-stage init-hook script and the persistence directory:
+
+```toml
+[[containers]]
+type = "aws"
+port = "4566"
+volumes = [
+ "./init/ready.d/init.sh:/etc/localstack/init/ready.d/init.sh", # ready init hook
+ "./data:/var/lib/localstack", # persistence mount
+]
+```
+
+Init-hook script naming and behavior differ per emulator; see the Initialization Hooks guide for your emulator ([AWS](/aws/configuration/config/initialization-hooks/), [Snowflake](/snowflake/capabilities/init-hooks/)) for the full details.
+
+Resolution rules:
+
+- Relative host sources (`./data`) are resolved against the **directory of the config file** that declared them, and a leading `~/` is expanded. This is required because the Docker SDK treats a non-absolute source as a *named volume* rather than a bind mount.
+- The entry whose container target is `/var/lib/localstack` defines the persistence directory — the same one `lstk volume path` and `lstk volume clear` act on. Precedence: a `volumes` entry targeting `/var/lib/localstack` → the legacy `volume` field → the default OS cache directory.
+- `volume` and `volumes` overlap only for the persistence mount. The legacy `volume` value is used **verbatim** (no path resolution); `volumes` sources are resolved. Setting the persistence directory via both `volume` and a `volumes` entry with different sources is a validation error.
+- The persistence directory is created automatically if missing; other `volumes` sources are expected to already exist (they are typically files, such as init hooks) and `lstk` errors if one is missing.
+
### Using a project-local config
Place a `.lstk/config.toml` in your project directory.
@@ -300,7 +331,11 @@ lstk start --non-interactive
| Option | Description |
|:--------------------|:-----------------------------------------------------------------------------|
| `--persist` | Persist emulator state across restarts (sets `LOCALSTACK_PERSISTENCE=1` in the container) |
-| `--non-interactive` | Disable the interactive TUI and use plain output |
+| `--snapshot [` | Snapshot `REF` to auto-load once the emulator starts, overriding the `snapshot` config field for this run |
+| `--no-snapshot` | Skip auto-loading the configured snapshot for this run |
+| `--non-interactive` | Disable the interactive TUI and use plain output (a global flag) |
+
+Host environment variables prefixed with `LOCALSTACK_` are forwarded to the emulator on start (the host `LOCALSTACK_AUTH_TOKEN` is dropped so it cannot override the token `lstk` resolves). See [Container-injected variables](#container-injected-variables).
By default the emulator starts with a fresh state on every run.
Pass `--persist` to keep data across restarts: `lstk` injects `LOCALSTACK_PERSISTENCE=1` into the container so state is written to the mounted [`volume`](#config-field-reference) and reloaded on the next start.
@@ -316,6 +351,23 @@ lstk start --persist
For finer-grained control, you can also set `PERSISTENCE = "1"` in an environment profile (see [Passing environment variables to the container](#passing-environment-variables-to-the-container)).
:::
+#### Auto-loading a snapshot on start
+
+The AWS emulator can auto-load a snapshot as it comes up.
+Set the `snapshot` field on the AWS `[[containers]]` block to any load `REF` — a `pod:` Cloud Pod, a local snapshot path, or an `s3://` location:
+
+```toml
+[[containers]]
+type = "aws"
+port = "4566"
+snapshot = "pod:my-baseline"
+```
+
+The snapshot is loaded only when the emulator is **freshly started** this run (it is skipped when the emulator is already running).
+Override the configured `REF` for a single run with `lstk start --snapshot ][`, or skip auto-loading entirely with `lstk start --no-snapshot`.
+An invalid `REF` fails before the emulator starts.
+`snapshot save` never writes this field back — it is set manually.
+
### `stop`
Stop the running LocalStack emulator.
@@ -470,15 +522,135 @@ By default, `lstk` probes whether `localhost.localstack.cloud` resolves to `127.
Set [`LOCALSTACK_HOST`](#environment-variables) to override the host:port used to reach LocalStack and skip the DNS probe.
The port comes from the AWS container's `port` in `config.toml` (default `4566`).
+### `az`
+
+Run Azure CLI commands against the running LocalStack Azure emulator.
+`lstk az ` runs `az ` with an isolated `AZURE_CONFIG_DIR` in which a custom Azure cloud (`LocalStack`) is registered against LocalStack's endpoints, so your global `~/.azure` configuration is left untouched and plain `az` keeps talking to real Azure.
+
+```bash
+lstk az group list
+lstk az storage account list
+```
+
+Run [`lstk setup azure`](#setup-azure) once before using this mode.
+`lstk az` requires the `az` CLI on your `PATH`, a healthy Docker runtime, a running Azure emulator, and that `*.localhost.localstack.cloud` resolves to `127.0.0.1` (the Azure emulator serves its endpoints under that host). Set [`LOCALSTACK_HOST`](#environment-variables) to override the host.
+
+Everything after `lstk az` is forwarded verbatim to the host `az` binary; its exit code and `stdout`/`stderr` pass through unchanged.
+
+#### `az start-interception` / `az stop-interception`
+
+An opt-in interception mode mutates your **global** `~/.azure` configuration so plain `az` (in any terminal or script) targets LocalStack, then switches it back.
+
+```bash
+lstk az start-interception # global 'az' now targets LocalStack
+lstk az stop-interception # switch back to real Azure
+```
+
+- `start-interception` registers and activates the `LocalStack` cloud in `~/.azure` and disables instance discovery, so existing `az` scripts run unmodified against LocalStack. It is independent of `lstk setup azure`.
+- `stop-interception` switches the active cloud back to `AzureCloud` (override with `--cloud `) and re-enables instance discovery — but only if `LocalStack` is still the active cloud, to avoid clobbering an unrelated selection.
+
+### `terraform`
+
+Proxy Terraform commands to LocalStack, injecting LocalStack endpoints as AWS provider overrides so your existing configuration runs unchanged. Aliased as `lstk tf`.
+
+```bash
+lstk terraform init
+lstk terraform --region us-west-2 plan
+lstk tf apply
+```
+
+`lstk`-specific flags must appear **before** the Terraform subcommand:
+
+| Flag | Description |
+|:--------------------|:------------------------------------------------------------------|
+| `--region ` | Deployment region (default `us-east-1`; falls back to `AWS_REGION`). |
+| `--account ` | Target AWS account id, 12 digits (default `test`; falls back to `AWS_ACCESS_KEY_ID`). |
+
+Commands that don't contact AWS (`fmt`, `validate`, `version`, and `init` when no S3 backend is declared) run without a running emulator; everything else requires the AWS emulator to be running and Docker healthy.
+
+Supported environment variables:
+
+| Variable | Description |
+|:-----------------------------|:---------------------------------------------------------------------|
+| `AWS_ENDPOINT_URL` | Override the auto-resolved LocalStack endpoint. |
+| `LSTK_TF_CMD` | Terraform binary to invoke (e.g. `tofu`; default `terraform`). |
+| `LSTK_TF_OVERRIDE_FILE_NAME` | Provider-override file name (default `localstack_providers_override.tf`). |
+| `LSTK_TF_DRY_RUN` | Generate the override file but do not run Terraform. |
+| `AWS_REGION` | Fallback for `--region`. |
+| `AWS_ACCESS_KEY_ID` | Fallback for `--account`. |
+
+### `cdk`
+
+Proxy AWS CDK commands to the running LocalStack emulator.
+Requires the AWS CDK CLI version `2.177.0` or newer on your `PATH`.
+
+```bash
+lstk cdk bootstrap
+lstk cdk --region us-west-2 deploy
+lstk cdk synth
+```
+
+CDK always targets the default LocalStack account `000000000000`; there is **no** `--account` flag (passing one is an error). The `--region ` flag (default `us-east-1`, falling back to `AWS_REGION`) must appear before the CDK action.
+
+Offline subcommands (e.g. `synth`) run without a running emulator; deploy-time commands require the AWS emulator to be running.
+
+Supported environment variables:
+
+| Variable | Description |
+|:----------------------|:-----------------------------------------------------|
+| `AWS_ENDPOINT_URL` | Override the auto-resolved LocalStack endpoint. |
+| `AWS_ENDPOINT_URL_S3` | Override the auto-derived S3 endpoint. |
+| `LSTK_CDK_CMD` | CDK binary to invoke (default `cdk`). |
+| `AWS_REGION` | Fallback for `--region`. |
+
+:::note
+If `localhost.localstack.cloud` does not resolve and `lstk` falls back to `127.0.0.1`, CDK's S3 asset operations (bootstrap, asset deploys) may fail virtual-host addressing. Ensure the host resolves, or set `AWS_ENDPOINT_URL`/`AWS_ENDPOINT_URL_S3` to a virtual-host-capable endpoint.
+:::
+
+### `sam`
+
+Proxy AWS SAM CLI commands to the running LocalStack emulator.
+Requires the AWS SAM CLI version `1.95.0` or newer on your `PATH` (older versions ignore `AWS_ENDPOINT_URL` and would target real AWS).
+
+```bash
+lstk sam build
+lstk sam --region us-west-2 deploy
+lstk sam validate
+```
+
+`lstk`-specific flags must appear **before** the SAM action:
+
+| Flag | Description |
+|:--------------------|:------------------------------------------------------------------|
+| `--region ` | Deployment region (default `us-east-1`; falls back to `AWS_REGION`). |
+| `--account ` | Target AWS account id, 12 digits (default `000000000000`; falls back to `AWS_ACCESS_KEY_ID`). |
+
+Offline subcommands (e.g. `build`, `validate`) run without a running emulator; deploy-time commands require the AWS emulator to be running.
+
+Supported environment variables:
+
+| Variable | Description |
+|:----------------------|:------------------------------------------------|
+| `AWS_ENDPOINT_URL` | Override the auto-resolved LocalStack endpoint. |
+| `AWS_ENDPOINT_URL_S3` | Override the S3 endpoint. |
+| `LSTK_SAM_CMD` | SAM binary to invoke (default `sam`). |
+| `AWS_REGION` | Fallback for `--region`. |
+| `AWS_ACCESS_KEY_ID` | Fallback for `--account`. |
+
+:::note
+Compared to `samlocal`, image/container-based Lambda (ECR) deploys and nested CloudFormation stacks are not supported; use `samlocal` for those workflows.
+:::
+
### `snapshot`
Manage emulator snapshots.
-A snapshot captures the running AWS emulator's state, either as a local file on disk or as a Cloud Pod on the LocalStack platform.
-The `snapshot` command groups four subcommands — `save`, `load`, `list`, and `remove`. The first two are also exposed as the top-level aliases `lstk save` and `lstk load`.
+A snapshot captures the running emulator's state — as a local file on disk, a Cloud Pod on the LocalStack platform, or an object in your own S3 bucket.
+The `snapshot` command groups five subcommands — `save`, `load`, `list`, `remove`, and `show`. The first two are also exposed as the top-level aliases `lstk save` and `lstk load`.
:::note
-`snapshot`, `save`, `load`, and [`reset`](#reset) operate on the **AWS emulator** only.
-If no AWS emulator is configured or running, they error out (`snapshot is only supported for the AWS emulator`).
+`snapshot` works with any emulator, but the AWS emulator is the well-tested path.
+For the Snowflake and Azure emulators, snapshot support is still maturing, so `snapshot` commands print a warning (`Snapshot support for the emulator is experimental and not fully tested.`) — results may be incomplete.
+[`reset`](#reset), by contrast, operates on the **AWS emulator only** and errors out otherwise (`reset is only supported for the AWS emulator`).
:::
#### `snapshot save`
@@ -495,18 +667,29 @@ lstk snapshot save ./my-snapshot
# Save to a Cloud Pod on the LocalStack platform (requires auth)
lstk snapshot save pod:my-baseline
+
+# Save to your own S3 bucket (pod name optional, auto-generated when omitted)
+lstk snapshot save my-pod s3://my-bucket/prefix
+lstk snapshot save my-pod s3://my-bucket/prefix --profile my-aws-profile
```
-The optional `[destination]` argument takes one of three forms:
+The optional `[destination]` argument takes one of these forms:
| Destination | Description |
|:-------------------|:------------------------------------------------------------------------------------------------|
-| (omitted) | Auto-generates a timestamped snapshot file in the current directory. |
-| local path | Writes a snapshot archive to that path. |
+| (omitted) | Auto-generates a timestamped `.snapshot` file in the current directory. |
+| local path | Writes a snapshot file to that path (the `.snapshot` extension is forced). |
| `pod:` | Saves a Cloud Pod to the LocalStack platform. Requires authentication. |
+| `s3://bucket/prefix` | Saves into your own S3 bucket. The pod name is a separate positional (auto-generated when omitted). |
Pod operations require an auth token (`LOCALSTACK_AUTH_TOKEN` or a prior `lstk login`); local-file snapshots do not.
+| Option | Description |
+|:--------------------|:---------------------------------------------------------------------------------------------|
+| `--profile ` | AWS profile to read S3 credentials from (S3 destinations only). |
+
+For S3 destinations, credentials follow AWS CLI precedence: `--profile ` wins, otherwise the static `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` (with optional `AWS_SESSION_TOKEN`), otherwise the profile named by `AWS_PROFILE`. Only static credentials are supported (no SSO, assume-role, or credential-process). Never put credentials in the URL. See [S3 remotes](#s3-remotes).
+
#### `snapshot load`
Load a snapshot into the emulator, **auto-starting it first** if it is not already running.
@@ -519,15 +702,19 @@ lstk snapshot load ./checkpoint
# Load from a Cloud Pod (requires auth)
lstk snapshot load pod:my-baseline
+# Load from your own S3 bucket (pod name required)
+lstk snapshot load my-pod s3://my-bucket/prefix --profile my-aws-profile
+
# Control how the snapshot merges with running state
lstk snapshot load pod:my-baseline --merge=overwrite
```
-The `REF` argument is required and identifies a local path/name or a `pod:` Cloud Pod.
+The `REF` argument is required and identifies a local path/name, a `pod:` Cloud Pod, or (with a separate pod-name positional) an `s3://` location. Older `.zip` snapshots saved by earlier `lstk` versions are still accepted.
| Option | Description |
|:---------------------|:--------------------------------------------------------------------------------------------------------|
| `--merge ` | How the loaded state combines with running state. One of `account-region-merge` (default), `overwrite`, `service-merge`. |
+| `--profile ` | AWS profile to read S3 credentials from (S3 sources only; see [S3 remotes](#s3-remotes)). |
- `account-region-merge` (default): the snapshot wins on any `(service, account, region)` overlap.
- `overwrite`: running state is reset first, then the snapshot is imported onto a clean state.
@@ -552,11 +739,20 @@ lstk snapshot list
# Every snapshot in your organization
lstk snapshot list --all
+
+# List snapshots in your own S3 bucket (requires a running emulator)
+lstk snapshot list s3://my-bucket/prefix --profile my-aws-profile
```
-| Option | Description |
-|:--------|:------------------------------------------------------------|
-| `--all` | List all snapshots in your organization, not just your own. |
+| Option | Description |
+|:-------------------|:------------------------------------------------------------|
+| `--all` | List all snapshots in your organization, not just your own. |
+| `--profile ` | AWS profile to read S3 credentials from (S3 listings only). |
+
+:::note
+`lstk snapshot list` (Cloud Pods) queries the LocalStack platform and does not need a running emulator.
+`lstk snapshot list s3://…`, by contrast, queries a **running emulator** (which performs the S3 transfer), so an emulator must be up. See [S3 remotes](#s3-remotes).
+:::
#### `snapshot remove`
@@ -577,6 +773,27 @@ The required `REF` argument must be a `pod:` Cloud Pod reference.
|:----------|:----------------------------------------------------------------------|
| `--force` | Skip the confirmation prompt. Required when running non-interactively. |
+#### `snapshot show`
+
+Show metadata for a single Cloud Pod snapshot on the LocalStack platform: name, created date, size, LocalStack version, message, services, and per-service resource counts (resource counts render only when the platform has them for that snapshot).
+Cloud-only and requires authentication.
+
+```bash
+lstk snapshot show pod:my-baseline
+```
+
+The required `REF` argument must be a `pod:` Cloud Pod reference.
+
+#### S3 remotes
+
+`snapshot save`, `load`, and `list` can target your own S3 bucket with an `s3://bucket/prefix` location.
+The pod name (the snapshot's identity within the bucket) is a positional argument separate from the `s3://` location — required for `load`, auto-generated for `save` when omitted, and unused for `list`.
+
+- **Credentials** follow AWS CLI precedence: `--profile ` wins, otherwise static `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` (with optional `AWS_SESSION_TOKEN`), otherwise the profile named by `AWS_PROFILE`. Only static credentials are supported (no SSO, assume-role, or credential-process). Credentials are never accepted in the URL.
+- **The emulator performs the transfer**, not the CLI; credentials are passed as ephemeral parameters on each operation and are never persisted.
+- Before each operation, `lstk` runs a bucket-existence pre-flight check and errors out rather than letting the emulator auto-create a bucket on a typo.
+- `remove`, `show`, and snapshot versions are **not** yet supported on S3 remotes; ORAS and other remote types are not supported.
+
### `reset`
Discard the running AWS emulator's in-memory state (all created resources such as S3 buckets and Lambda functions are dropped).
@@ -731,22 +948,26 @@ If a LocalStack emulator is still running after logout, `lstk` prints a note rem
### `setup`
Set up CLI integration for an emulator type.
-`lstk setup` is a grouping command with no action of its own; the work is done by its subcommand.
-Currently only AWS is supported.
+`lstk setup` is a grouping command with no action of its own; the work is done by its subcommands (`aws` and `azure`).
```bash
lstk setup aws
+lstk setup azure
```
#### `setup aws`
Create or update a `localstack` profile in `~/.aws/config` and `~/.aws/credentials` so the AWS CLI and SDKs can target LocalStack.
-This command requires an interactive terminal and prompts before making any changes.
```bash
lstk setup aws
+lstk setup aws --force
```
+| Option | Description |
+|:----------|:--------------------------------------------------------------------------------------------------|
+| `--force` | Skip the confirmation prompt and overwrite an existing `localstack` profile whose values differ. |
+
It writes the following profile (existing unrelated profiles are preserved):
```ini
@@ -775,10 +996,10 @@ The port comes from your AWS emulator's configured `port` (default `4566`); if n
If the `localstack` profile is already configured correctly, `lstk` reports `LocalStack AWS profile is already configured.` and makes no changes.
+On an interactive terminal, `setup aws` prompts (Y/n) before writing. Overwriting an existing `localstack` profile whose values differ requires `--force` (which also skips the prompt); writing a fresh profile, completing a partial one, or leaving an already-correct profile unchanged never needs it.
+
:::note
-`setup aws` requires an interactive terminal.
-In non-interactive mode (piped output, CI, or `--non-interactive`) it fails with `setup aws requires an interactive terminal`.
-There is no flag to auto-confirm.
+In non-interactive mode (piped output, CI, or `--non-interactive`), `setup aws` does not prompt — it writes the profile with defaults and exits `0`. A write or check failure returns a non-zero exit code so automation fails loudly.
:::
:::caution
@@ -786,6 +1007,19 @@ There is no flag to auto-confirm.
It still works and behaves identically, but you should use `lstk setup aws` instead.
:::
+#### `setup azure`
+
+Prepare an isolated Azure CLI config directory (under the `lstk` config dir, via `AZURE_CONFIG_DIR`) that routes [`lstk az`](#az) commands to the LocalStack Azure emulator.
+It registers a custom Azure cloud (`LocalStack`) pointing at LocalStack's Azure endpoints, activates it, disables Azure CLI instance discovery and telemetry, and performs a one-time dummy service-principal login.
+Your global `~/.azure` configuration is left untouched.
+
+```bash
+lstk setup azure
+```
+
+Requires the `az` CLI on your `PATH` and a running LocalStack Azure emulator.
+Run this once; afterwards use `lstk az ` to run Azure CLI commands against LocalStack.
+
### `config`
Manage CLI configuration.
@@ -912,6 +1146,8 @@ These options are available for all commands:
| `--config ` | Path to a specific TOML config file |
| `--non-interactive` | Disable the interactive TUI, use plain output |
| `--persist` | Persist emulator state across restarts (on `start`/bare `lstk` and `restart`) |
+| `--snapshot ][` | Snapshot `REF` to auto-load after start (on `start`/bare `lstk`; overrides config for the run) |
+| `--no-snapshot` | Skip auto-loading the configured snapshot for the run (on `start`/bare `lstk`) |
| `-v`, `--version` | Print the version and exit |
| `-h`, `--help` | Print help and exit |
@@ -930,9 +1166,9 @@ lstk --non-interactive start
```
:::note
-`lstk login` and `lstk setup aws` require an interactive terminal.
+`lstk login` requires an interactive terminal.
If you need to authenticate in CI, set `LOCALSTACK_AUTH_TOKEN` instead.
-Commands that mutate state without prompting in CI (`reset`, `volume clear`) require `--force`.
+`setup aws` runs non-interactively (it writes the profile with defaults), but commands that mutate state without prompting in CI (`reset`, `volume clear`, `snapshot remove`) require `--force`.
:::
## Environment variables
diff --git a/src/content/docs/aws/developer-tools/security-testing/iam-policy-grammar.md b/src/content/docs/aws/developer-tools/security-testing/iam-policy-grammar.md
new file mode 100644
index 000000000..031744d6b
--- /dev/null
+++ b/src/content/docs/aws/developer-tools/security-testing/iam-policy-grammar.md
@@ -0,0 +1,130 @@
+---
+title: IAM Policy Grammar
+description: Condition operators and condition keys supported by the LocalStack IAM policy engine.
+template: doc
+tags: ["Base"] # TODO: confirm tier
+sidebar:
+ order: 5
+---
+
+
+
+## Introduction
+
+This page lists the IAM policy grammar that the LocalStack policy engine can evaluate: the [condition operators](#condition-operators) and [condition keys](#condition-keys) it understands when checking a request.
+The same engine backs both [IAM Policy Enforcement](/aws/developer-tools/security-testing/iam-policy-enforcement/) and the [IAM Policy Simulator](/aws/developer-tools/security-testing/iam-policy-simulator/), so the support described here applies to both.
+
+Grammar support is expanding over time; operators and keys not listed here may not yet be evaluated.
+For which service actions are covered, see the [IAM coverage documentation](/aws/developer-tools/security-testing/iam-coverage/), which tracks action coverage rather than grammar.
+
+## Condition operators
+
+The [`Condition`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html) element of a policy statement uses condition operators to compare a condition key against a value.
+The tables below list the operators the engine supports, grouped by category.
+
+
+
+### String
+
+| Operator | Supported |
+| --- | --- |
+| `StringEquals` | Verify |
+| `StringNotEquals` | Yes |
+| `StringEqualsIgnoreCase` | Verify |
+| `StringNotEqualsIgnoreCase` | Yes |
+| `StringLike` | Verify |
+| `StringNotLike` | Yes |
+
+### Numeric
+
+| Operator | Supported |
+| --- | --- |
+| `NumericEquals` | Yes |
+| `NumericNotEquals` | Yes |
+| `NumericLessThan` | Yes |
+| `NumericLessThanEquals` | Yes |
+| `NumericGreaterThan` | Yes |
+| `NumericGreaterThanEquals` | Yes |
+
+### ARN
+
+| Operator | Supported |
+| --- | --- |
+| `ArnEquals` | Verify |
+| `ArnLike` | Verify |
+| `ArnNotEquals` | Yes |
+| `ArnNotLike` | Yes |
+
+### Other categories
+
+
+
+## Condition keys
+
+In addition to the global (`aws:*`) condition keys, the engine evaluates the following service-specific keys.
+
+| Condition key | Purpose |
+| --- | --- |
+| `iam:PolicyArn` | Restrict policy attach/detach operations to specific policies. |
+| `s3:max-keys` | Numeric key for the maximum number of keys returned by a listing. |
+
+
+
+## Examples
+
+The expanded grammar makes it possible to express organization- and account-level guardrails locally.
+The following statement is illustrative; confirm the exact condition-key names against your LocalStack version.
+
+Limit the page size of an S3 listing by denying requests that ask for more than 100 keys, using a numeric operator with the `s3:max-keys` key:
+
+```json showLineNumbers
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Deny",
+ "Action": "s3:ListBucket",
+ "Resource": "*",
+ "Condition": {
+ "NumericGreaterThan": { "s3:max-keys": "100" }
+ }
+ }
+ ]
+}
+```
+
+
+
+## Known limitations
+
+Grammar support is rolled out incrementally, so operators and keys not listed above may not yet be evaluated.
+
+
+
+## Related
+
+- [IAM Policy Enforcement](/aws/developer-tools/security-testing/iam-policy-enforcement/)
+- [IAM Policy Simulator](/aws/developer-tools/security-testing/iam-policy-simulator/)
+- [IAM Coverage](/aws/developer-tools/security-testing/iam-coverage/)
+- [Explainable IAM](/aws/developer-tools/security-testing/explainable-iam/)
\ No newline at end of file
diff --git a/src/content/docs/aws/enterprise/kubernetes/configuration.md b/src/content/docs/aws/enterprise/kubernetes/configuration.md
index df509e804..962783e63 100644
--- a/src/content/docs/aws/enterprise/kubernetes/configuration.md
+++ b/src/content/docs/aws/enterprise/kubernetes/configuration.md
@@ -11,9 +11,9 @@ When LocalStack runs on Kubernetes with the Kubernetes executor enabled, a set o
### Namespace
-By default, LocalStack creates child pods in the `default` namespace. Use `LOCALSTACK_K8S_NAMESPACE` to deploy them into a different namespace.
+By default, LocalStack creates child pods in the `default` namespace. Use `K8S_NAMESPACE` to deploy them into a different namespace.
```bash
-LOCALSTACK_K8S_NAMESPACE=localstack-workloads
+K8S_NAMESPACE=localstack-workloads
```
The namespace must already exist in your cluster before starting LocalStack.
@@ -24,18 +24,18 @@ You can attach custom Kubernetes labels and annotations to all child pods create
Both variables accept a comma-separated list of `key=value` pairs:
```bash
-LOCALSTACK_K8S_LABELS=env=dev,team=platform
-LOCALSTACK_K8S_ANNOTATIONS=prometheus.io/scrape=true,prometheus.io/port=8080
+K8S_LABELS=env=dev,team=platform
+K8S_ANNOTATIONS=prometheus.io/scrape=true,prometheus.io/port=8080
```
### Pod configuration
-`LOCALSTACK_K8S_POD_CONFIG` configures Kubernetes metadata, scheduling, and resource settings for child pods created by supported services such as Lambda and ECS.
+`K8S_POD_CONFIG` configures Kubernetes metadata, scheduling, and resource settings for child pods created by supported services such as Lambda and ECS.
Use it to define reusable pod profiles with fields such as `nodeSelector`, `tolerations`, `affinity`, `resources`, `labels`, and `annotations`.
The value must be valid JSON.
```bash
-LOCALSTACK_K8S_POD_CONFIG='{"profiles":{"default":{"nodeSelector":{"pool":"general"}}}}'
+K8S_POD_CONFIG='{"profiles":{"default":{"nodeSelector":{"pool":"general"}}}}'
```
For the full JSON schema, profile resolution order, and examples, see [Pod Configuration](/aws/enterprise/kubernetes/pod-configuration/).
@@ -88,10 +88,10 @@ Increase these values if your cluster is under heavy load or if image pulls are
| Variable | Description |
|---|---|
-| `LOCALSTACK_K8S_NAMESPACE` | Kubernetes namespace for child pods |
-| `LOCALSTACK_K8S_LABELS` | Comma-separated `key=value` labels applied to child pods |
-| `LOCALSTACK_K8S_ANNOTATIONS` | Comma-separated `key=value` annotations applied to child pods |
-| `LOCALSTACK_K8S_POD_CONFIG` | JSON pod configuration for supported child pods. See [Pod Configuration](/aws/enterprise/kubernetes/pod-configuration/) |
+| `K8S_NAMESPACE` | Kubernetes namespace for child pods |
+| `K8S_LABELS` | Comma-separated `key=value` labels applied to child pods |
+| `K8S_ANNOTATIONS` | Comma-separated `key=value` annotations applied to child pods |
+| `K8S_POD_CONFIG` | JSON pod configuration for supported child pods. See [Pod Configuration](/aws/enterprise/kubernetes/pod-configuration/) |
| `K8S_CONTAINER_SECURITY_CONTEXT` | JSON security context applied to child pod containers |
| `K8S_CURL_INIT_IMAGE` | Init container image used for network readiness checks |
| `LAMBDA_K8S_INIT_IMAGE` | Init container image used in Lambda pods |
diff --git a/src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md b/src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md
index 8716c4e27..422408eee 100644
--- a/src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md
+++ b/src/content/docs/aws/enterprise/kubernetes/kubernetes-executor.md
@@ -45,7 +45,7 @@ For more information, see the [Helm Chart configuration](https://github.com/loca
- Kubernetes Lambda Executor in LocalStack scales Lambda execution by spawning new environments (running in pods) during concurrent invocations.
Inactive environments shut down after 10 minutes (configurable via `LAMBDA_KEEPALIVE_MS`).
- Executor schedules multiple Lambda functions according to Kubernetes cluster defaults without specifying node affinity.
- Users can assign labels to lambda pods using the `LAMBDA_K8S_LABELS` variable (e.g., `LAMBDA_K8S_LABELS=key=value,key2=value2`).
+ Users can assign labels to lambda pods using the `K8S_LABELS` variable (e.g., `K8S_LABELS=key=value,key2=value2`).
- Timeout configurations similar to AWS are enforced using the `Timeout` function parameter.
No intrinsic limits on the number of Lambdas; default limit on concurrent executions is 1000 (`LAMBDA_LIMITS_CONCURRENT_EXECUTIONS`).
- Custom DNS configuration for Lambda on Kubernetes can be set through the `LAMBDA_DOCKER_DNS` configuration variable.
diff --git a/src/content/docs/aws/enterprise/kubernetes/pod-configuration.md b/src/content/docs/aws/enterprise/kubernetes/pod-configuration.md
index 7f32bf12e..b2c05c51c 100644
--- a/src/content/docs/aws/enterprise/kubernetes/pod-configuration.md
+++ b/src/content/docs/aws/enterprise/kubernetes/pod-configuration.md
@@ -12,7 +12,7 @@ tags: ["Enterprise"]
When LocalStack runs inside Kubernetes with the Kubernetes executor enabled, some services create child pods for workloads such as Lambda invocations and ECS tasks.
In heterogeneous clusters, these child pods may need additional Kubernetes configuration so they are scheduled onto the right node pools, carry the right resource requests, or integrate with cluster policies.
-Use the `LOCALSTACK_K8S_POD_CONFIG` environment variable to configure Kubernetes metadata, scheduling, and resource settings for LocalStack-spawned pods.
+Use the `K8S_POD_CONFIG` environment variable to configure Kubernetes metadata, scheduling, and resource settings for LocalStack-spawned pods.
The variable accepts a JSON object with reusable `profiles` and optional per-service mappings.
The value must be valid JSON. LocalStack validates this configuration at startup and refuses to start if the value is not valid JSON or contains unknown fields, so misconfigurations surface before any child pods are created.
@@ -77,7 +77,7 @@ To use this with the Helm chart, pass the JSON as an environment variable in you
```yaml
extraEnvVars:
- - name: LOCALSTACK_K8S_POD_CONFIG
+ - name: K8S_POD_CONFIG
value: |
{
"profiles": {
@@ -190,15 +190,15 @@ Use them only for global defaults.
Architecture values are normalized before lookup.
For example, `ARM64` is treated as `arm64`, and `x86_64` or `X86_64` are treated as `amd64`.
-The keys in `LOCALSTACK_K8S_POD_CONFIG` should still be `arm64` and `amd64`.
+The keys in `K8S_POD_CONFIG` should still be `arm64` and `amd64`.
If a service references a profile that does not exist, LocalStack logs a warning and applies no pod configuration for that request.
It does not silently fall back to `default`.
## Labels and annotations
-`labels` and `annotations` in `LOCALSTACK_K8S_POD_CONFIG` are merged into the metadata of the generated child pod.
-Profile labels override labels set through `LOCALSTACK_K8S_LABELS`, and profile annotations override annotations set through `LOCALSTACK_K8S_ANNOTATIONS`.
+`labels` and `annotations` in `K8S_POD_CONFIG` are merged into the metadata of the generated child pod.
+Profile labels override labels set through `K8S_LABELS`, and profile annotations override annotations set through `K8S_ANNOTATIONS`.
LocalStack also injects the following system labels:
@@ -257,8 +257,8 @@ The following example schedules Lambda pods on dedicated nodes, adds tolerations
## Related configuration
-- Use `LOCALSTACK_K8S_NAMESPACE` to choose the namespace for child pods.
-- Use `LOCALSTACK_K8S_LABELS` and `LOCALSTACK_K8S_ANNOTATIONS` for simple labels and annotations that apply to all child pods.
+- Use `K8S_NAMESPACE` to choose the namespace for child pods.
+- Use `K8S_LABELS` and `K8S_ANNOTATIONS` for simple labels and annotations that apply to all child pods.
- Use `K8S_CONTAINER_SECURITY_CONTEXT` to configure the security context for child pod containers.
For the complete list of Kubernetes executor configuration variables, see the [Kubernetes configuration reference](/aws/enterprise/kubernetes/configuration/).
diff --git a/src/content/docs/aws/services/ec2.mdx b/src/content/docs/aws/services/ec2.mdx
index 8669631f5..41ad58ce9 100644
--- a/src/content/docs/aws/services/ec2.mdx
+++ b/src/content/docs/aws/services/ec2.mdx
@@ -408,6 +408,9 @@ The token can be used in subsequent requests like so:
curl -H "x-aws-ec2-metadata-token: " -v http://169.254.169.254/latest/meta-data/
```
+You can use the [`ModifyInstanceMetadataOptions`](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifyInstanceMetadataOptions.html) API to change the metadata options of a running instance, for example to require IMDSv2.
+Parameters that are omitted from the request retain their current value, matching AWS behavior.
+
:::note
IMDS IPv6 endpoint is currently not supported.
:::
@@ -688,6 +691,26 @@ Any operation not listed below will use the mock VM manager.
| `TerminateInstances` | Stops and undefines a Libvirt domain |
| `CreateVolume` | Creates a sparse Libvirt volume |
+## IAM Condition Keys
+
+When [IAM Policy Enforcement](/aws/developer-tools/security-testing/iam-policy-enforcement/) is enabled, LocalStack supports the following EC2-specific condition keys, matching the behavior described in the [AWS condition keys reference](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html#amazonec2-policy-keys):
+
+- `ec2:MetadataHttpTokens` — the `HttpTokens` value of an instance's [metadata options](#instance-metadata-service), useful for enforcing IMDSv2.
+- `ec2:Attribute/` — exposes request parameters (e.g. `HttpTokens` on `ModifyInstanceMetadataOptions`) as condition keys.
+
+For example, the following policy statement only allows launching instances when IMDSv2 is required:
+
+```json
+{
+ "Effect": "Allow",
+ "Action": "ec2:RunInstances",
+ "Resource": "arn:aws:ec2:*:*:instance/*",
+ "Condition": {
+ "StringEquals": { "ec2:MetadataHttpTokens": "required" }
+ }
+}
+```
+
## Resource Browser
The LocalStack Web Application provides a Resource Browser for managing EC2 instances.
diff --git a/src/content/docs/aws/services/eks.mdx b/src/content/docs/aws/services/eks.mdx
index 661d2730a..ab316f0d7 100644
--- a/src/content/docs/aws/services/eks.mdx
+++ b/src/content/docs/aws/services/eks.mdx
@@ -98,7 +98,7 @@ The Traefik ingress controller and the default k3d load balancer containers are
To restore the previous behavior, set the following configuration variable:
```bash
-EKS_START_K3D_LB_INGRESS=1
+K3D_START_LB_INGRESS=1
```
:::
@@ -464,7 +464,7 @@ Two AMI families are supported:
LocalStack reads the same set of fields from both formats and propagates them to the registered node, including node labels, taints, topology metadata (region, zone, instance type), and the provider ID. This matches what real EKS nodes look like from the cluster's perspective.
:::note
-Self-managed nodes use the embedded k3d-backed provider (`EKS_K8S_PROVIDER=k3s`), which is the default.
+Self-managed nodes use the embedded k3d-backed provider (`MANAGED_K8S_PROVIDER=k3s`), which is the default.
The walkthrough below runs entirely between Docker containers, so it also works on macOS where direct host-to-instance networking is not available.
:::
@@ -640,7 +640,7 @@ To try this out, follow the upstream [Getting started with Karpenter](https://ka
## Use an existing Kubernetes installation
You can also access the EKS API using your existing local Kubernetes installation.
-This can be achieved by setting the configuration variable `EKS_K8S_PROVIDER=local` and mounting the `$HOME/.kube/config` file into the LocalStack container.
+This can be achieved by setting the configuration variable `MANAGED_K8S_PROVIDER=local` and mounting the `$HOME/.kube/config` file into the LocalStack container.
When using a `docker-compose.yml` file, you need to add a bind mount like this:
```yaml
@@ -875,15 +875,15 @@ The default version is `1.35`.
| 1.31 | v1.31.14-k3s1 | eks.60 |
| 1.30 | v1.30.14-k3s2 | eks.68 |
-Users can specify the desired version when creating an EKS cluster in LocalStack using the `EKS_K3S_IMAGE_TAG` configuration variable when starting LocalStack.
+Users can specify the desired version when creating an EKS cluster in LocalStack using the `K3S_IMAGE_TAG` configuration variable when starting LocalStack.
## Configuring the k3d Cluster Token
When LocalStack creates a k3d-backed EKS cluster, it starts the k3s server with an explicit cluster token. This token is used to authenticate agent nodes joining the cluster, enabling dynamic node registration.
-By default, LocalStack uses `localstack-k3d-cluster-token` as the cluster token. You can override this value using the `EKS_K3D_CLUSTER_TOKEN` configuration variable:
+By default, LocalStack uses `localstack-k3d-cluster-token` as the cluster token. You can override this value using the `K3D_CLUSTER_TOKEN` configuration variable:
```bash
-EKS_K3D_CLUSTER_TOKEN=my-custom-token localstack start
+K3D_CLUSTER_TOKEN=my-custom-token localstack start
```
Any agent nodes added to the cluster — whether via k3d node create or k3s agent — will use the same token to authenticate with the k3s server.
diff --git a/src/content/docs/aws/services/lambda.mdx b/src/content/docs/aws/services/lambda.mdx
index 22e86312b..1c068bf8e 100644
--- a/src/content/docs/aws/services/lambda.mdx
+++ b/src/content/docs/aws/services/lambda.mdx
@@ -290,8 +290,8 @@ import { Table, TableHeader, TableBody, TableHead, TableRow, TableCell } from '@
🟢
🟢
🟢
- ➖
- ➖
+ 🟠
+ 🟠
BisectBatchOnFunctionError
@@ -305,9 +305,9 @@ import { Table, TableHeader, TableBody, TableHead, TableRow, TableCell } from '@
ScalingConfig
- The scaling configuration for the event source.
- 🟠
- 🟠
+ The scaling configuration for the event source. [^3]
+ 🟡
+ 🟡
➖
➖
➖
@@ -375,9 +375,9 @@ import { Table, TableHeader, TableBody, TableHead, TableRow, TableCell } from '@
ProvisionedPollerConfig
- Control throughput via min-max limits.
- ➖
- ➖
+ Control throughput via min-max limits. [^4]
+ 🟡
+ 🟡
➖
➖
🟠
@@ -428,6 +428,8 @@ import { Table, TableHeader, TableBody, TableHead, TableRow, TableCell } from '@
[^1]: Read more at [Control which events Lambda sends to your function](https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventfiltering.html)
[^2]: The available Metadata properties may not have full parity with AWS depending on the event source (read more at [Understanding event filtering basics](https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventfiltering.html#filtering-basics)).
+[^3]: For SQS Standard, `ScalingConfig` is accepted but not automatically applied — the poller count is currently hard-coded rather than scaled based on `MaximumConcurrency`. For SQS FIFO, a single poller is always used to preserve message-group ordering, so the scaling configuration is accepted but has no effect.
+[^4]: For SQS Standard, only `MinimumPollers` is honored (it sets the poller count); `MaximumPollers` has no effect. For SQS FIFO, the single-poller model means the configuration is accepted but ignored.
Create a [GitHub Discussion](https://github.com/orgs/localstack/discussions/new/choose) or reach out to [LocalStack Support](/aws/help-support/get-help/) if you experience any challenges.
]