DEV Community

Peyton Green
Peyton Green

Posted on

LocalStack Now Requires an Account — Here's How to Test AWS in Python Without One in 2026

LocalStack archived its GitHub repo on March 23, 2026. The read-only notice went up quietly. No banner. No grace period announcement. Just a new requirement: LOCALSTACK_AUTH_TOKEN in your environment — or your CI pipeline fails.

If you're in a commercial team on the Hobby tier, you're also hit with a non-commercial-use restriction. The paid plans start at $39/month.

Update (March 24, 2026): LocalStack has since posted a blog announcement (blog.localstack.cloud) with staged concessions: unlimited CI, and a free Hobby tier for non-commercial use. Auth token is still required, and Hobby tier needs account creation. The core complaint — 'your CI breaks if you don't have a vendor account' — hasn't changed. The alternatives below don't require either.

I'm not going to relitigate whether this was the right call. It's their product. But I've been burned by this category of problem before: tool solves a real pain point with a good free tier, community adopts it into their CI configs and READMEs and onboarding docs, adoption metrics eventually justify monetization pressure, free tier gets changed, and your pipeline is broken at 3 AM before a release.

The failure mode isn't LocalStack specifically. It's vendor-gated infrastructure in your test suite. When the vendor changes something — pricing, auth, terms — your code is correct, your tests pass locally if you have the token, and your CI is broken for a reason that has nothing to do with the code.

Here's what I've migrated to, with working code you can drop in today.


Option 1: moto — Python-native, no Docker, no auth

For pure unit testing that was using LocalStack's S3, SQS, DynamoDB, or Lambda mocking, moto covers most of it.

moto is MIT-licensed, pure Python, no external service, no auth token, no account required. It intercepts boto3 calls in-process and tears down after each test.

pip install moto[s3,dynamodb,sqs,lambda]
Enter fullscreen mode Exit fullscreen mode

Basic usage:

import boto3
import pytest
from moto import mock_aws

@mock_aws
def test_upload_and_retrieve():
    s3 = boto3.client("s3", region_name="us-east-1")
    s3.create_bucket(Bucket="test-bucket")
    s3.put_object(Bucket="test-bucket", Key="test.txt", Body=b"hello")

    response = s3.get_object(Bucket="test-bucket", Key="test.txt")
    assert response["Body"].read() == b"hello"
Enter fullscreen mode Exit fullscreen mode

No auth token. No service running in the background. No Docker dependency. The decorator handles setup and teardown.

moto covers 200+ AWS services. For the common test suite needs — S3, DynamoDB, SQS, SNS, Lambda, IAM — it's a complete drop-in.

What it doesn't cover: complex cross-service workflows that depend on real network behavior, anything that required LocalStack Pro's multi-region state persistence, or services outside its 200+ API coverage. For the vast majority of Python unit tests, those edge cases don't apply.


The complete pytest conftest.py drop-in

If your project had a conftest.py using LocalStack fixtures, here's a complete replacement using moto. Copy this in, run your tests, they should pass.

# conftest.py — Drop-in AWS mocking for pytest
# Replaces LocalStack for unit/integration tests
# Covers: S3, DynamoDB, SQS

import boto3
import pytest
from moto import mock_aws


@pytest.fixture(scope="function")
def aws_credentials(monkeypatch):
    """Mock AWS credentials for moto."""
    monkeypatch.setenv("AWS_ACCESS_KEY_ID", "testing")
    monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "testing")
    monkeypatch.setenv("AWS_SECURITY_TOKEN", "testing")
    monkeypatch.setenv("AWS_SESSION_TOKEN", "testing")
    monkeypatch.setenv("AWS_DEFAULT_REGION", "us-east-1")


@pytest.fixture(scope="function")
@mock_aws
def s3_client(aws_credentials):
    """S3 client with mocked AWS backend."""
    return boto3.client("s3", region_name="us-east-1")


@pytest.fixture(scope="function")
@mock_aws
def dynamodb_client(aws_credentials):
    """DynamoDB client with mocked AWS backend."""
    return boto3.client("dynamodb", region_name="us-east-1")


@pytest.fixture(scope="function")
@mock_aws
def sqs_client(aws_credentials):
    """SQS client with mocked AWS backend."""
    return boto3.client("sqs", region_name="us-east-1")


@pytest.fixture(scope="function")
@mock_aws
def test_s3_bucket(s3_client):
    """Pre-created S3 bucket for tests."""
    s3_client.create_bucket(Bucket="test-bucket")
    return "test-bucket"


@pytest.fixture(scope="function")
@mock_aws
def test_queue(sqs_client):
    """Pre-created SQS queue for tests."""
    response = sqs_client.create_queue(QueueName="test-queue")
    return response["QueueUrl"]
Enter fullscreen mode Exit fullscreen mode

This covers the 80% case: S3 + DynamoDB + SQS together. Add Lambda and SNS fixtures following the same pattern if needed.

Free download: I've packaged this with the extended version (SNS, Lambda, Secrets Manager fixtures included) as a free script. Download the full conftest.py here → (Kit landing page — coming soon)


Option 2: Floci — if you need a running container

Python unit tests? If you're writing Python tests and want something battle-tested with no new dependencies, Moto (8,300 GitHub stars, no daemon, no auth, in-process) may serve you better. Floci is for integration flows that need real network endpoints across multiple services.

If your integration tests require hitting an actual running service (not just boto3 interception), Floci is the drop-in LocalStack Community Edition replacement that appeared on HN the same week LocalStack made their change.

One more reason this gap matters: as of March 23, 2026, even the LocalStack community Docker image now requires an auth token — breaking the Testcontainers+LocalStack zero-auth workflow that many teams relied on. There is now no mature, zero-auth multi-service AWS emulator except Floci. That changes the calculus on recommending a young project.

  • Port 4566 compatible — zero code changes from LocalStack. Your LOCALSTACK_HOST=localhost config still works.
  • MIT license. No auth required. No account. No token.
  • 138x faster startup than LocalStack (24ms vs 3.3s), 91% less memory (~90MB vs ~1GB)
  • 22 AWS service families including S3, DynamoDB, SQS, SNS, Lambda (Python runtime supported), API Gateway, IAM, CloudWatch

Replace your docker-compose LocalStack service:

# before:
localstack:
  image: localstack/localstack
  environment:
    - LOCALSTACK_AUTH_TOKEN=${LOCALSTACK_AUTH_TOKEN}
  ports:
    - "4566:4566"

# after:
floci:
  image: hectorvent/floci:latest
  ports:
    - "4566:4566"
Enter fullscreen mode Exit fullscreen mode

Remove the auth token environment variable. That's the migration.

Floci is at github.com/hectorvent/floci. It launched on HN with 95 points the same week as the LocalStack change — the timing is not a coincidence. As of March 23, 2026 it's at v1.0.5 with 1,500+ stars and active development.

The tradeoff: Floci covers the core service set, not LocalStack's full 80+ service catalog. If you're testing IAM role propagation edge cases or Route53 behaviors, you may need more. For S3/SQS/Lambda/DynamoDB workloads, it covers the common case.

Maturity caveat: Floci is the only zero-auth multi-service AWS emulator available today — it fills a gap LocalStack just created. That matters. But be aware: the project is ~35 days old, AI-assisted in origin, and has open API parity gaps (Ruby Lambda unsupported, S3 upload limit at 27MB, SQS JSON routing bugs). It's appropriate for personal projects and dev environments. For team CI/CD or security-sensitive pipelines, treat it as beta and watch the issue tracker.


Option 3: CloudDev — if your tests are IaC-driven

If your tests are closer to infrastructure validation than unit tests — Terraform or CDK configs you want to verify locally — CloudDev is worth a look.

  • Single Go binary, no runtime dependencies
  • clouddev detect auto-detects your IaC config
  • Web dashboard at localhost:4580
  • Free and open-source

One note: CloudDev has a Dev.to post from the builder that's worth reading before adopting — it's honest about the current service coverage. If your tests are Python unit tests hitting AWS service mocks, moto is still the right choice. CloudDev is for a slightly different use case.


Option 4: The service-specific tools

For specific services where you need something standalone:

  • MinIO for S3-compatible object storage: docker run -p 9000:9000 minio/minio server /data — S3-compatible API, Apache-licensed, production deployable, no vendor account
  • ElasticMQ for SQS: lightweight in-memory SQS implementation, runs as a JAR
  • DynamoDB Local — AWS's own tool, downloadable JAR, no account required, free

None of these require vendor accounts. None of them can break your CI by changing a pricing page.


The pattern that caused this, and how to protect against it

LocalStack isn't the first tool to pull this. Docker Desktop changed its licensing for enterprise users. HashiCorp changed Terraform to BSL. Elasticsearch changed its license. The pattern is consistent:

  1. Tool solves a real pain point with a good free tier
  2. Community adopts it deeply — CI configs, READMEs, onboarding docs
  3. Adoption becomes the leverage for monetization
  4. Terms change
  5. You're stuck because migration cost is high and deadline is now

The problem isn't vendor monetization — that's reasonable. The problem is vendor-gated tooling in development-time infrastructure. Test tooling is particularly vulnerable because:

  • CI pipelines are sticky. Once something works, it doesn't get touched until it breaks.
  • Breakage is time-sensitive. CI failure blocks deploy. You don't negotiate from that position.
  • Dev tooling auth tokens are often stored as CI secrets — one more credential to rotate when breached.

The design principle I follow: dev tooling that runs locally should not require a network call to a vendor service to execute. If moto or Floci can cover your use case, they should. Not because LocalStack was bad — it was genuinely useful — but because vendor-gated test execution is a class of failure mode you can avoid.


Which tool for which situation

Situation Tool
Unit tests, boto3 mocking, no Docker needed moto
Integration tests, need running service, was using LocalStack container floci
IaC-driven tests (Terraform/CDK) clouddev
S3-compatible object storage minio
SQS simulation elasticmq
DynamoDB local DynamoDB Local (AWS JAR)

Getting the conftest.py fixture

I've put together a drop-in conftest.py with fixtures for S3, DynamoDB, SQS, SNS, and Lambda that you can drop into any Python project. Free download.

This is one of the scripts in the Python Automation Cookbook — 25 production-ready scripts built on the same principle: no auth gates, no vendor accounts, no subscriptions required to run them. If the pricing page changes, your scripts still work.

Download the free conftest.py + early access to Automation Cookbook → (Kit landing page — coming soon)

Python Automation Cookbook — $39 one-time. 25 production-ready Python scripts.


Tags: #python #testing #aws #devtools #pytest
Series: Python AWS Testing Without the Subscription Tax — Part 1


The conftest.py fixtures above cover the 80% case for S3/DynamoDB/SQS. moto v5.1.22 was released March 8, 2026. Floci was last updated ~March 2026. Check GitHub for current versions before adding to production.

Top comments (1)

Collapse
 
peytongreen_dev profile image
Peyton Green

Just tested this setup — the moto approach works great for CI. The conftest pattern alone saved us from running a full LocalStack instance in GH Actions.