Repository navigation
Replace the deprecated localstack CLI with lstk in Samples CI and the sample guides - #135
Merged
Merged
Conversation
…ck CLI The legacy `localstack` CLI is deprecated and no longer receives updates. Samples CI now drives the emulator with lstk end to end: - The Start, Retry and Get LocalStack Logs steps use lstk start, stop and logs. The container is now named localstack-azure. - Container settings move from DOCKER_FLAGS and bare variables to LOCALSTACK_-prefixed ones, which lstk forwards and the image's entrypoint strips. ACTIVATE_PRO goes: nothing in the image reads it. - lstk is installed before the emulator starts and moves from 0.19.0 to 1.4.0. The Podman detection regression behind the 0.19.0 pin was fixed in 0.20.1 (localstack/lstk#422), and DOCKER_HOST now pins the daemon for every lstk call in the job. - The container removes itself, logs included, when it exits. The Start and Retry steps keep a copy of its logs, which Get LocalStack Logs prints when the emulator is gone, as the old CLI did itself. - run-samples.sh and `make logs` use lstk, and the localstack package leaves requirements-runtime.txt: nothing imports it. This does not fix the current "License activation failed" (exit 55). The license server rejects TEST_LOCALSTACK_AUTH_TOKEN itself, and lstk hands the token to the container exactly as the old CLI did. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Terraform sample that fails leaves its state behind: run-samples.sh removes it only after a successful run. The CI retry then deploys the sample again on a fresh emulator, and terraform plan first refreshes the old state there. Data-plane resources fail that refresh instead of dropping out of state - a storage table cannot find its account - so the retry failed before deploying anything, whatever had failed the first attempt (url-shortener/python/terraform in run 38376597563). run-samples.sh now removes terraform.tfstate, its backup and tfplan before a Terraform sample deploys. The provider cache in .terraform is kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…timeouts The Start step's comments explained the expired readiness waits as stalled boots. They were not: every "Emulator was not ready within 400s" warning in five full Samples CI runs between 2026-09-18 and 2026-10-13 - 27 timeouts in 23 jobs - was a ready emulator the old localstack CLI failed to notice. The CLI waits for a log line reading exactly "Ready.". The emulator prints that marker in two writes, and the Azurite container of its managed storage account logs from another thread at the same moment, so a line can land between them: "Ready.2026-10-13T09:30:02.013 DEBUG ...". Each timed-out emulator had been ready about ten seconds after it started. lstk polls the health endpoint and never reads that marker, so the move to lstk removes these false timeouts; a longer timeout would only have made each of them longer. The comments now describe only what lstk does. Get LocalStack Logs now prints the copy of the logs that the Start and Retry steps keep, which covers every emulator the job ran. On a retried job, make logs showed only the retry's emulator, so the logs of the emulator that failed were never printed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The qrcodes container is publicly readable (container_access_type = "blob"), but azurerm 5.x creates storage accounts with allow_nested_items_to_be_public = false unless told otherwise, and Azure does not let a container grant anonymous access on an account that denies it: creating the container fails with 409 PublicAccessNotPermitted. The emulator enforces this since localstack-pro #9198 (2026-10-07). url-shortener/python/terraform passed in the last full Samples CI run before it and failed in the first one after. The scripts and Bicep variants already allow public blob access on the account. The setting is a variable with a default of true, like the sample's other settings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Sample documentation still instructs users to run the removed localstack CLI.
1 open finding
What changed in this PR
Migrates sample CI from the deprecated localstack CLI to lstk, improves retries and logging, and fixes public blob access.
Changes:
- Uses
lstkfor emulator lifecycle and diagnostics. - Resets Terraform state before retries.
- Enables public QR-code blob access.
| File | Description |
|---|---|
.github/workflows/run-samples.yml |
Migrates CI emulator management to lstk. |
.claude/settings.json |
Removes developer-local settings. |
Makefile |
Uses lstk for logs. |
requirements-runtime.txt |
Removes the deprecated CLI dependency. |
run-samples.sh |
Starts with lstk and resets Terraform state. |
samples/url-shortener/python/terraform/main.tf |
Enables configurable public blob access. |
samples/url-shortener/python/terraform/variables.tf |
Defines the public-access setting. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…toml The sample READMEs and docs/LOCALSTACK.md started the emulator with the deprecated localstack CLI (IMAGE_NAME=... localstack start -d, then localstack wait), while 45 of them listed only lstk among their prerequisites, so a reader who followed them had no localstack command. They now run lstk start --type azure, which returns once the emulator is ready, and list the lstk CLI, linked to its documentation, where they listed LocalStack. docs/LOCALSTACK.md also stops the emulator with lstk stop and reads its logs with lstk logs. pyproject.toml no longer depends on the localstack package, and the workflow no longer mentions the old CLI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Motivation
Samples CI starts the emulator, waits for it and reads its logs with the
localstackCLI, which is deprecated and no longer receives updates: every job printsWARNING: The 'localstack' CLI is deprecated. Use the 'lstk' CLI instead.The workflow already installs lstk, but only forlstk az start-interception. The sample READMEs anddocs/LOCALSTACK.mdstart the emulator with the same CLI (IMAGE_NAME=localstack/localstack-azure localstack start -d, thenlocalstack wait), while 45 of them list only lstk among their prerequisites, so a reader who follows them has nolocalstackcommand.The last run on
main(38376597563) shows three more problems, which this PR also fixes:Emulator was not ready within 400sand started a new emulator, although each emulator had been ready about ten seconds after it started.localstack waitwaits for a log line reading exactlyReady., and the emulator prints that marker in two writes (print(constants.READY_MARKER_OUTPUT, flush=True)in localstack-pro'slocalstack-core/localstack/runtime/runtime.py) while the Azurite container of its managed storage account logs from another thread, so a line can land between them:Ready.2026-10-13T09:30:02.013 DEBUG --- [ Thread-4] .... All 27 timeouts in five full runs between 2026-09-18 and 2026-10-13 (23 jobs) were this. A longer timeout would only make each one longer. lstk polls/_localstack/healthand never reads the marker.url-shortener/python/terraformfails with409 PublicAccessNotPermittedwhen it creates itsqrcodescontainer. The container is publicly readable (container_access_type = "blob"), but azurerm 5.x creates storage accounts withallow_nested_items_to_be_public = falseunless told otherwise (provider source), and "If anonymous access is denied for the storage account, you can't configure anonymous access for a container" (Configure anonymous read access for containers and blobs). The emulator enforces this since localstack-pro#9198 (2026-10-07): the sample passed in the last full run before it and failed in the first one after. The Azure CLI and Bicep variants of the sample already allow public blob access on the account.terraform planfirst refreshes resources that no longer exist. A storage table cannot find its account, and the url-shortener retry failed with404 ResourceNotFoundbefore deploying anything.Fixes SMF-939
Changes
run-samples.ymlrunlstk start,lstk stopandlstk logsinstead ofpython -m localstack_cli.cli.mainandlocalstack logs, and the emulator container is nowlocalstack-azure.run-samples.shstarts the emulator withlstk start, which returns at once in CI where the workflow has already started it, and no longer requires thelocalstackCLI.make logsrunslstk logs --verbose, and thelocalstackpackage leavesrequirements-runtime.txtandpyproject.toml.docs/LOCALSTACK.mdstart the emulator withlstk start --type azure, which returns once the emulator is ready, instead oflocalstack startandlocalstack wait. Where a prerequisites list named LocalStack, it now names the lstk CLI.docs/LOCALSTACK.mdstops the emulator withlstk stopand reads its logs withlstk logs. No file in the repository runs the old CLI any more.DOCKER_HOSTnow names the Docker daemon for every lstk call in the job.DOCKER_FLAGSand the bareLS_LOG,DISABLE_EVENTSandDNS_ADDRESSbecomeLOCALSTACK_-prefixed variables, which lstk forwards to the container and the image's entrypoint strips.ACTIVATE_PROgoes: nothing in the image reads it.run-samples.shremoves a Terraform sample'sterraform.tfstate, its backup andtfplanbefore deploying it.url-shortener/python/terraform. The storage account setsallow_nested_items_to_be_publicfrom a newstorage_allow_nested_items_to_be_publicvariable that defaults totrue..claude/settings.jsonis removed: it held one developer's local Claude Code permissions, with absolute paths to a local checkout.Tests
Each changed step of
run-samples.ymlreplayed locally from the workflow file (the step'srun:block with itsenv:, a freshHOME, lstk 1.4.0,localstack/localstack-azure:latestof 2026-10-13):url-shortener/python/scripts: Start, Run and Retry pass, and the emulator reports ready within seconds.License activation failed!and the license server's reason (exit code 55), instead ofError: timeout.url-shortener/python/terraform: before the fixes, the first attempt reproduces the409 PublicAccessNotPermitted; with only the sample fix, the retry over the leftover state reproduces the404 ResourceNotFound; with both, the retry deploys from scratch (27 resources) andvalidate.shpasses. The committed workflow then passes Start, Run, Retry and Get LocalStack Logs, which prints the logs of both emulators.samples/url-shortener/python/README.md, run in a terminal on a machine with no lstk configuration:lstk start --type azurereturns once the emulator is running,az group createreaches the emulator afterlstk az start-interception, andlstk stopstops it.The CI of this PR runs all 91 jobs, and is the first time lstk starts the emulator on the arm64 runners.
Related
🤖 Generated with Claude Code