|
| 1 | +--- |
| 2 | +title: lstk Automation & CI |
| 3 | +description: Global options, non-interactive mode, structured JSON output, environment variables, tracing, and logging for scripting lstk. |
| 4 | +template: doc |
| 5 | +tags: ['Hobby'] |
| 6 | +--- |
| 7 | + |
| 8 | +## Global options |
| 9 | + |
| 10 | +These options are available for all commands: |
| 11 | + |
| 12 | +| Option | Description | |
| 13 | +|:--------------------|:------------------------------------------------------------------------------| |
| 14 | +| `--config <path>` | Path to a specific TOML config file | |
| 15 | +| `--non-interactive` | Disable the interactive TUI, use plain output | |
| 16 | +| `--json` | Emit a single machine-readable JSON envelope on stdout instead of human-oriented output. Supported by `stop`, `reset`, and `update`; any other command rejects it. See [Structured output](#structured-output). | |
| 17 | +| `--persist` | Persist emulator state across restarts (on `start`/bare `lstk` and `restart`) | |
| 18 | +| `--type <type>`, `-t <type>` | Emulator type to start: `aws`, `snowflake`, or `azure` (on `start`/bare `lstk`; records the choice in config). See [Selecting the emulator with `--type`](/azure/developer-tools/lstk/lifecycle-commands/#selecting-the-emulator-with---type). | |
| 19 | +| `--snapshot <REF>` | Snapshot REF to auto-load after start (on `start`/bare `lstk`; overrides config for one run) | |
| 20 | +| `--no-snapshot` | Skip auto-loading the configured snapshot (on `start`/bare `lstk`) | |
| 21 | +| `--timeout <duration>` | Startup readiness deadline for `start`/bare `lstk`, as a Go duration; overrides `LSTK_STARTUP_TIMEOUT` for one run. See [`start`](/azure/developer-tools/lstk/lifecycle-commands/#start). | |
| 22 | +| `-v`, `--version` | Print the version and exit | |
| 23 | +| `-h`, `--help` | Print help and exit | |
| 24 | + |
| 25 | +## Interactive and non-interactive mode |
| 26 | + |
| 27 | +`lstk` automatically selects its output mode: |
| 28 | + |
| 29 | +- **Interactive mode** (TUI): used when both stdin and stdout are connected to a terminal. |
| 30 | + Commands like `start`, `stop`, `restart`, `status`, `login`, `update`, and the confirmation prompts of `reset`/`volume clear` display a Bubble Tea-powered terminal UI. |
| 31 | +- **Non-interactive mode** (plain text): used when the output is piped, redirected, or running in CI. |
| 32 | + Force this in a TTY with `--non-interactive`. |
| 33 | + |
| 34 | +```bash |
| 35 | +# Force plain output even in an interactive terminal |
| 36 | +lstk --non-interactive start |
| 37 | +``` |
| 38 | + |
| 39 | +:::note |
| 40 | +`lstk login` requires an interactive terminal; if you need to authenticate in CI, set `LOCALSTACK_AUTH_TOKEN` instead. |
| 41 | +Commands that mutate state without prompting in CI (`reset`, `volume clear`) require `--force`. |
| 42 | +`lstk setup aws` works non-interactively — it writes the profile with defaults and needs `--force` only to overwrite a conflicting `localstack` profile. |
| 43 | +::: |
| 44 | + |
| 45 | +## Structured output |
| 46 | + |
| 47 | +The global `--json` flag makes a command emit a single, machine-readable JSON object on stdout instead of human-oriented text, for scripting and CI. |
| 48 | +JSON support is available per command: `stop`, `reset`, and `update` accept `--json`. |
| 49 | +Any other command rejects it with an error envelope (`error.code: NOT_JSON_CAPABLE`) rather than silently printing plain text. |
| 50 | + |
| 51 | +Every JSON-capable command writes **exactly one** JSON object with the following envelope shape: |
| 52 | + |
| 53 | +```json |
| 54 | +{ |
| 55 | + "schemaVersion": 1, |
| 56 | + "command": "stop", |
| 57 | + "status": "ok", |
| 58 | + "data": { |
| 59 | + "emulators": [ |
| 60 | + { "type": "aws", "name": "localstack-aws", "wasRunning": true } |
| 61 | + ] |
| 62 | + }, |
| 63 | + "warnings": [], |
| 64 | + "error": null |
| 65 | +} |
| 66 | +``` |
| 67 | + |
| 68 | +| Field | Type | Description | |
| 69 | +|:----------------|:-----------------|:--------------------------------------------------------------------------------------------------------| |
| 70 | +| `schemaVersion` | integer | Wire-format version of the envelope, always `1` for this schema. Check it once before parsing. | |
| 71 | +| `command` | string | The command that produced the envelope (e.g. `"stop"`, `"reset"`). | |
| 72 | +| `status` | string | `"ok"` or `"error"` — branch on this first. | |
| 73 | +| `data` | object or `null`| Command-specific result. Non-null when `status` is `"ok"`, `null` when it is `"error"`. | |
| 74 | +| `warnings` | array | Non-fatal notices, always present (empty array when there are none). Each entry is `{ "code", "message" }`. | |
| 75 | +| `error` | object or `null`| The machine-readable failure. Non-null when `status` is `"error"`, `null` otherwise. | |
| 76 | + |
| 77 | +When `status` is `"error"`, the `error` object carries a stable `code` (e.g. `EMULATOR_NOT_RUNNING`, `CONFIRMATION_REQUIRED`, `RUNTIME_UNAVAILABLE`), a coarse `category`, a human-readable `message` (informational only — branch on `code`, not `message`), and a `retryable` boolean: |
| 78 | + |
| 79 | +```json |
| 80 | +{ |
| 81 | + "schemaVersion": 1, |
| 82 | + "command": "reset", |
| 83 | + "status": "error", |
| 84 | + "data": null, |
| 85 | + "warnings": [], |
| 86 | + "error": { |
| 87 | + "code": "CONFIRMATION_REQUIRED", |
| 88 | + "category": "USAGE", |
| 89 | + "message": "reset requires confirmation; use --force to skip in non-interactive mode", |
| 90 | + "retryable": false |
| 91 | + } |
| 92 | +} |
| 93 | +``` |
| 94 | + |
| 95 | +### Exit codes |
| 96 | + |
| 97 | +For a full enumeration, read `error.code` from the envelope; the process exit code carries only the two most common, mechanically-remediable failures: |
| 98 | + |
| 99 | +| Exit code | Meaning | |
| 100 | +|:----------|:-------------------------------------------------------------------------------------------| |
| 101 | +| `0` | `status: "ok"`. | |
| 102 | +| `1` | `status: "error"` for any code other than the two below. | |
| 103 | +| `2` | A Cobra-level usage error that occurred before `--json` could be recognized (plain-text error on stderr, not an envelope). | |
| 104 | +| `3` | `error.code == "CONFIRMATION_REQUIRED"` (re-run with `--force`). | |
| 105 | +| `4` | `error.code == "AUTH_REQUIRED"` (run `lstk login` or set `LOCALSTACK_AUTH_TOKEN`). | |
| 106 | + |
| 107 | +:::note |
| 108 | +`--json` implies non-interactive behavior: no TUI and no prompts. |
| 109 | +Combining it with a destructive command that would otherwise prompt (`reset`) still requires `--force`, which surfaces as `CONFIRMATION_REQUIRED` (exit code `3`) when omitted. |
| 110 | +::: |
| 111 | + |
| 112 | +## Environment variables |
| 113 | + |
| 114 | +The following environment variables configure `lstk` itself (not the LocalStack container): |
| 115 | + |
| 116 | +| Variable | Description | |
| 117 | +|:-------------------------------|:---------------------------------------------------------------------------------------------------------------------| |
| 118 | +| `LOCALSTACK_AUTH_TOKEN` | Auth token for non-interactive runs or to skip browser login. Used when no keyring token is stored. | |
| 119 | +| `LOCALSTACK_HOST` | Override the host (and optional port) used when resolving and printing the emulator endpoint, and when writing the AWS CLI profile. Bypasses the `localhost.localstack.cloud` DNS probe. | |
| 120 | +| `LOCALSTACK_DISABLE_EVENTS` | Set to `1` to disable anonymous telemetry event reporting. | |
| 121 | +| `DOCKER_HOST` | Override the Docker daemon socket (e.g. `unix:///home/user/.colima/default/docker.sock`). | |
| 122 | +| `LSTK_KEYRING` | Set to `file` to force file-based token storage instead of the system keyring. | |
| 123 | +| `LSTK_STARTUP_TIMEOUT` | Startup readiness deadline for `lstk start`, as a Go duration (e.g. `90s`, `2m`). Zero/unset uses the per-mode default (20s interactive, 60s non-interactive). See [`start`](/azure/developer-tools/lstk/lifecycle-commands/#start). | |
| 124 | +| `LSTK_MERGE_STRATEGY` | Default merge strategy for `snapshot load` / `load` (`account-region-merge`, `overwrite`, or `service-merge`) when `--merge` is not passed. An explicit `--merge` always wins. | |
| 125 | +| `LSTK_OTEL` | Set to `1` to enable OpenTelemetry trace export (disabled by default). See [OpenTelemetry tracing](#opentelemetry-tracing). | |
| 126 | +| `LSTK_GITHUB_TOKEN` | Optional GitHub token used when checking for or downloading `lstk` updates (raises GitHub API rate limits). | |
| 127 | +| `LSTK_API_ENDPOINT` | Override the LocalStack platform API base URL. Default: `https://api.localstack.cloud`. | |
| 128 | +| `LSTK_WEB_APP_URL` | Override the LocalStack Web Application URL used for browser login. Default: `https://app.localstack.cloud`. | |
| 129 | + |
| 130 | +When `DOCKER_HOST` is not set, `lstk` tries the default Docker socket and then probes common alternatives (Colima at `~/.colima/default/docker.sock` or `~/.config/colima/default/docker.sock`, OrbStack at `~/.orbstack/run/docker.sock`). |
| 131 | + |
| 132 | +When `LSTK_OTEL` is enabled, the standard `OTEL_EXPORTER_OTLP_*` environment variables are honored by the OpenTelemetry SDK. |
| 133 | + |
| 134 | +### Container-injected variables |
| 135 | + |
| 136 | +`lstk` injects several environment variables into the LocalStack container on every start, in addition to any profiles you configure: |
| 137 | + |
| 138 | +| Variable | Default value | Description | |
| 139 | +|:-----------------------------|:-------------------------------------------------|:---------------------------------------------| |
| 140 | +| `LOCALSTACK_AUTH_TOKEN` | (your resolved token) | Passed from the CLI to activate the license. | |
| 141 | +| `GATEWAY_LISTEN` | `:4566,:443` | Ports the emulator binds inside the container. | |
| 142 | +| `MAIN_CONTAINER_NAME` | `localstack-aws` | Container name for internal references. | |
| 143 | +| `LOCALSTACK_HOST` | `localhost.localstack.cloud:<host port>` | Hostname/port the emulator advertises. | |
| 144 | +| `LOCALSTACK_PERSISTENCE` | `1` (only with `--persist`) | Enables state persistence across restarts. | |
| 145 | +| `LOCALSTACK_CLIENT_NAME` | `lstk` | Identifies the client that started the emulator. | |
| 146 | +| `LOCALSTACK_CLIENT_VERSION`| (the `lstk` version) | Version of the client that started the emulator. | |
| 147 | + |
| 148 | +When a Docker socket is detected it is bind-mounted into the container and `DOCKER_HOST=unix:///var/run/docker.sock` is injected so the emulator can spawn its own containers. |
| 149 | +`lstk` also forwards host environment variables matching `CI` and `LOCALSTACK_*` (the host `LOCALSTACK_AUTH_TOKEN` is dropped so it cannot override the token resolved by `lstk`). |
| 150 | + |
| 151 | +The container also gets port mappings for `4566`, `443`, and the service port range `4510-4559`. |
| 152 | + |
| 153 | +:::note |
| 154 | +`GATEWAY_LISTEN` is read from the container's resolved environment (set it via an `[env.*]` profile), not hardcoded. |
| 155 | +Beyond controlling which ports the emulator binds, its host part sets the host publish IP for all published ports: a value like `GATEWAY_LISTEN = "0.0.0.0:4566,0.0.0.0:443"` exposes the emulator beyond loopback (e.g. on a remote host), whereas the default binds to `127.0.0.1` only. |
| 156 | +::: |
| 157 | + |
| 158 | +## OpenTelemetry tracing |
| 159 | + |
| 160 | +`lstk` can export traces of its own command execution over OTLP/HTTP. |
| 161 | +Tracing is **disabled by default**. |
| 162 | +Enable it with: |
| 163 | + |
| 164 | +```bash |
| 165 | +LSTK_OTEL=1 lstk start |
| 166 | +``` |
| 167 | + |
| 168 | +When enabled, every command is wrapped in a span (e.g. `lstk.start`) recording the exit code and any error. |
| 169 | +`lstk` does not hardcode an export target, so the OpenTelemetry Go SDK reads the standard `OTEL_EXPORTER_OTLP_*` environment variables automatically (default target: OTLP/HTTP at `localhost:4318`). |
| 170 | +You need an OTLP-compatible backend running to receive the traces. |
| 171 | + |
| 172 | +## Logging |
| 173 | + |
| 174 | +`lstk` writes its own diagnostic logs to `lstk.log` in the same directory as the active config file. |
| 175 | +This is separate from the LocalStack container logs (which you view with [`lstk logs`](/azure/developer-tools/lstk/lifecycle-commands/#logs)). |
| 176 | + |
| 177 | +- The log file is created automatically and appended to across runs. |
| 178 | +- When the file exceeds **1 MB**, it is cleared on the next run. |
| 179 | +- Use `lstk config path` to find the config directory; `lstk.log` sits alongside `config.toml`. |
0 commit comments