Repository navigation
Migrate every sample from the localstack CLI to lstk - #277
Open
HarshCasper wants to merge 8 commits into
Open
HarshCasper wants to merge 8 commits into
HarshCasper wants to merge 8 commits into
Conversation
Replace the localstack CLI with lstk across all samples, the archived samples, the root Makefile and README, and CI: - check/install targets look for lstk and install it with npm - start runs lstk start --non-interactive --type aws; settings the old CLI forwarded implicitly now carry the LOCALSTACK_ prefix that lstk forwards (DEBUG, EC2_VM_MANAGER, ENFORCE_IAM, SERVICES) - ready/logs/stop use lstk status, lstk logs and lstk stop - the Lambda debugging SAM samples mount their debug config through a project .lstk/config.toml instead of --volume - route53-dns-failover and java-notification-app manage LocalStack with Docker Compose, so they wait on the health endpoint and use docker compose logs/down instead of either CLI - CI installs lstk instead of the localstack Python package and passes LOCALSTACK_DEBUG and LOCALSTACK_DNS_ADDRESS - READMEs link the lstk docs and use lstk start / lstk login Claude-Session: https://claude.ai/code/session_01DZfDmzUBPqNAu3yFKyfCNM
lstk aws runs the AWS CLI against LocalStack with the endpoint, credentials and region set, and lstk tf runs Terraform with the LocalStack provider overrides, so the separate wrappers are no longer needed: - every awslocal call is now lstk aws, and every tflocal call lstk tf - check targets look for the aws binary lstk aws runs, and install targets no longer pip install awscli-local - README prerequisites list the AWS CLI and Terraform, used through lstk aws and lstk tf - CI installs the AWS CLI (v1, as awscli-local[ver1] did) instead of awscli-local Claude-Session: https://claude.ai/code/session_01DZfDmzUBPqNAu3yFKyfCNM
- Without a localstack AWS profile, lstk aws prints a setup note on stdout, so scripts that pipe its output into jq fail. CI now runs lstk setup aws after installing lstk, and the README tells users to run it once. - The localstack/localstack image no longer ships curl, so the EMR Serverless dependencies image installs it before fetching Poetry. Claude-Session: https://claude.ai/code/session_01DZfDmzUBPqNAu3yFKyfCNM
route53-dns-failover and java-notification-app start LocalStack with Docker Compose but call the AWS CLI through lstk aws, so their check targets look for lstk again, and route53-dns-failover installs it. Claude-Session: https://claude.ai/code/session_01DZfDmzUBPqNAu3yFKyfCNM
Fargate tasks use awsvpc networking, where AWS requires the host port to equal the container port. RegisterTaskDefinition now rejects the old 45139 -> 80 mapping on LocalStack too, rolling back the stack. Drop the HostPort parameter; make run already reads the bound port from the task's network bindings. Claude-Session: https://claude.ai/code/session_01DZfDmzUBPqNAu3yFKyfCNM
lstk aws reads AWS_ACCESS_KEY_ID only as a 12-digit account id and drops any other value once the localstack profile exists, so calls meant to run as the ls-a/ls-b IAM users ran with the profile's root credentials and the access-denied check passed by mistake. Those calls now use the AWS CLI with the LocalStack endpoint; the account-id calls keep using lstk aws. DEBUG also gets the LOCALSTACK_ prefix lstk forwards. Claude-Session: https://claude.ai/code/session_01DZfDmzUBPqNAu3yFKyfCNM
- serverless-websockets: test.py connected to the API endpoint without a stage path, which LocalStack now rejects with HTTP 401 (AWS needs the stage too). It now appends the deployed stage. - glue-msk-schema-registry: Kafka can take more than the 140s the script waited for the MSK cluster to become ACTIVE on a busy runner. Wait up to about 5 minutes. Claude-Session: https://claude.ai/code/session_01DZfDmzUBPqNAu3yFKyfCNM
The handler returned the raw event, which isn't a valid Lambda proxy response; LocalStack now rejects the connection with HTTP 502, as AWS does. Return statusCode 200 and echo the message body, which API Gateway sends back to the client on routes with a route response. Claude-Session: https://claude.ai/code/session_01DZfDmzUBPqNAu3yFKyfCNM
remotesynth
approved these changes
Oct 16, 2026
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.
Moves the whole repository from the
localstackCLI tolstk, following the patternelb-load-balancingset in #271. It also replaces theawslocalandtflocalwrappers withlstk awsandlstk tf. After this PR, no sample, README, script or workflow invokes or installs the old CLI,awslocalortflocal.What changed
Makefiles (44 samples and the archived ones):
checklooks forlstk, andinstallrunsnpm install -g @localstack/lstkinstead ofpip install localstack.startrunslstk start --non-interactive --type aws.readyrunslstk status(lstk startalready waits for LocalStack to be ready),logsrunslstk logs > logs.txt, andstoprunslstk stop.Settings the old CLI forwarded implicitly: lstk only forwards
LOCALSTACK_-prefixed variables to the container, so they now carry the prefix:DEBUGbecomesLOCALSTACK_DEBUG.EC2_VM_MANAGER(ec2-docker-instances).export ENFORCE_IAM=1(iam-policy-enforcement,multi-account-multi-region-s3-access).export SERVICES=...(athena-s3-queries,cognito-jwt,glacier-s3-select,neptune-graph-dband archived samples).Lambda debugging SAM samples (Java, JavaScript, Python, TypeScript): lstk has no
--volumeflag, so each sample gets a.lstk/config.tomlthat mountslambda_debug_mode_config.yaml. lstk reads it when run from the sample directory. The debug mode variables were alreadyLOCALSTACK_-prefixed, andIMAGE_NAMEis gone, since lstk's AWS emulator is the Pro image.Docker Compose samples:
route53-dns-failoverandjava-notification-appstart LocalStack with Docker Compose. They only used the CLI to wait for, read logs from, or stop that container. They now:/_localstack/healthdocker compose logs localstackdocker compose downemr-serverless-python-dependenciesstarts with lstk, so itsstopis nowlstk stopinstead of adocker compose downthat never stopped that container.READMEs: the prerequisite bullet links the lstk docs.
localstack startexamples are nowlstk startwith prefixed variables, and the root README useslstk logininstead oflocalstack auth set-token. Its Makefile template is updated as well.Scripts:
glue-etl-jobs/run.shuseslstk logs.awslocalandtflocal:lstk awsruns the AWS CLI with the LocalStack endpoint, credentials and region set, andlstk tfruns Terraform with the LocalStack provider overrides, so:awslocalcall is nowlstk aws, and everytflocalcall islstk tf(Makefiles, scripts, READMEs)checktargets look for theawsbinarylstk awsruns, andinstalltargets no longerpip install awscli-locallstk awsandlstk tfCI (
test.yml): installs lstk with npm instead of thelocalstackPython package, and the AWS CLI (v1, asawscli-local[ver1]did) instead ofawscli-local. It passesLOCALSTACK_DEBUGandLOCALSTACK_DNS_ADDRESS, since plainDEBUG/DNS_ADDRESSno longer reach the container.Fixes found by running every sample on lstk
lstk setup aws. Without thelocalstackAWS profile,lstk awsprints a setup note on stdout. That broke every script piping its output intojq, and madecloudformation packageupload to real S3. The root README tells users to runlstk setup awsonce.multi-account-multi-region-s3-access: with the profile in place,lstk awsreadsAWS_ACCESS_KEY_IDonly as a 12-digit account id and drops IAM-user access keys. The calls signed as thels-a/ls-busers therefore use the AWS CLI with the LocalStack endpoint. The account-id calls keeplstk aws.route53-dns-failover,java-notification-app: these run LocalStack with Docker Compose but calllstk aws, so they require lstk again.Sample bugs that the current LocalStack image now rejects, as AWS does:
ecs-ecr-container-app: Fargate tasks useawsvpc, where the host port must equal the container port. The 45139 → 80 mapping is dropped.serverless-websockets: the test now connects to the stage URL (no stage gives HTTP 401). The handler now returns a proper proxy response (the raw event gave HTTP 502).Environment changes:
emr-serverless-python-dependencies:localstack/localstack:latestno longer shipscurl, so the build image installs it before fetching Poetry.glue-msk-schema-registry: the MSK wait is now about 5 minutes. LocalStack downloads Kafka on first use, and that download was slow on some runners.Not changed on purpose
cdklocalandsamlocal. lstk haslstk cdkandlstk sam, butlstk samdoesn't support container-image Lambdas or nested stacks yet, so these are left for a follow-up.sample-archive/sagemaker-ml-jobsstillpip installslocalstackinto its virtualenv, becauserun_job.pyimports it as a library (from localstack.utils.aws import aws_stack).Checks
make -npasses forstart,stop,readyandlogsin every changed Makefile, and actionlint passes on the workflow. CI passes for all 47 jobs: https://github.com/localstack-samples/localstack-pro-samples/actions/runs/38747440649