dozeGitHubGet doze
doze AWS

Wakes AWS on your laptop. No account, no bill.

Part of the doze family. Works alone.

Stop waiting on a deploy to find out if your Lambda works. Stop sharing one dev account with the whole team. 17 services in one Go binary, speaking the real wire protocols, so your SDK, the AWS CLI, SAM and CDK point at it unchanged. No Docker, no JVM.

waiting for CloudFormation…AccessDenied (the shared dev account)works on my machine, fails in AWS
on its ownloopback only
$ doze-aws

  doze-aws is up.

    endpoint  http://127.0.0.1:4566
    console   http://127.0.0.1:4566/_console/
    serving   17 services in us-east-1

    eval "$(doze-aws env)"   point this shell at it
    doze-aws doctor          when something looks wrong

$ aws sts get-caller-identity
{ "Account": "000000000000", … }
The console

It opens on your own traffic.

Every call your app makes, newest first, with what it was on, how AWS would have answered, and how long it took. Real AWS cannot show you this, because it is not sitting between your code and the answer.

The doze AWS console's wire: every AWS call the app made, newest first, with one PutItem refused
1 call was refusedThe same request would fail on AWS. You found out on your laptop.

The real console, from its demo stack: your traffic, not a diagram. re-capture with Larder

Watch it fill up. Real AWS CLI calls (S3 uploads, SQS jobs, DynamoDB writes) land on the wire as they happen.
A refused PutItem opened: its request, and the ledger entry for the operation
Open the refused one. What you sent, why it was refused, a request id you can quote, and copy as curl.
Not just the wire

Every service gets a real console.

Browse buckets, peek at queues, query tables, invoke functions and read their logs, follow a state machine, and generate the IAM policy your tests needed. One binary, no cloud account.

01 / 08 · The map

See how your stack is wired.

A topic feeding a queue, its dead-letter queue, a rule targeting a function: every resource wired to another, and the wire between.

the real console, from its demo stack · re-capture with Larder
The doze AWS map: order-events feeds jobs, which redrives to jobs-dlq; the receipts rule targets the resize function
02 / 08 · Lambda

Functions are real host processes.

Invoke one and see the response and its log tail: here a Node function in 2.32 ms. No Docker. Warm, and it sleeps after 10 idle minutes.

the real console, from its demo stack · re-capture with Larder
The resize Lambda: triggers, warm state, a successful invoke with its response and log tail
03 / 08 · DynamoDB

Browse and query tables.

Scan, query, get and PartiQL, the way you would on AWS. GSIs, transactions and TTL underneath.

the real console, from its demo stack · re-capture with Larder
The orders table: six items with scan, query, get and PartiQL
04 / 08 · S3

Buckets on your disk.

Browse and upload, with event notifications to SQS, SNS and Lambda, as on AWS.

the real console, from its demo stack · re-capture with Larder
The uploads bucket with three receipts
05 / 08 · SQS

Peek at a queue without consuming it.

What feeds it, where its dead letters go, and every message. FIFO, DLQ redrive and long polling.

the real console, from its demo stack · re-capture with Larder
The jobs queue: five messages, fed by order-events, dead letters to jobs-dlq
06 / 08 · EventBridge

A rule, its pattern, its targets.

The full pattern language, cron and rate schedules, input transformers, and what each rule drains to.

the real console, from its demo stack · re-capture with Larder
The receipts rule with its event pattern and its Lambda target
07 / 08 · Step Functions

Follow a state machine.

Standard and Express, JSONata, task tokens and Map runs, with every execution, succeeded and failed.

the real console, from its demo stack · re-capture with Larder
The checkout state machine with a succeeded and a failed execution
08 / 08 · IAM

The policy your tests actually needed.

Real policy evaluation, on by default in soft mode: evaluated and logged, never blocked. Run your tests, then generate the least-privilege policy they used.

the real console, from its demo stack · re-capture with Larder
The IAM access log: every action recorded, a policy generator and a simulator

17 services that talk to each other.

An S3 upload fires EventBridge, which invokes a Lambda, which writes to DynamoDB, with IAM policies evaluated on the way, as on AWS.

  • S3buckets, objects, notifications
  • SQSFIFO, DLQ redrive, long polling
  • SNSfanout, filter policies
  • DynamoDBexpressions, GSI/LSI, transactions
  • Lambdahost processes, no Docker
  • Step FunctionsStandard and Express, JSONata
  • EventBridgepatterns, schedules, targets
  • API GatewayREST and HTTP APIs into Lambda
  • IAMreal policy evaluation
  • CloudFormationsam deploy, cdk deploy
  • Kinesisresharding, no JVM
  • CloudWatchmetrics, alarms
  • CloudWatch Logsgroups, streams, tail --follow
  • KMSreal stdlib crypto
  • Secrets Managerversion stages, encrypted
  • SSM Parameter Storeversions, labels, SecureString
  • STSidentity, assume role
  • All 17, in the docs →what each one does, and how faithfully
Works alone

On its own, or inside a doze stack.

The same binary either way. On its own it answers on loopback. Inside doze it gets a name, wakes when your code calls and sleeps when it stops.

On its own

One command, one address.

Run doze-aws and point your tools at 127.0.0.1:4566; the console is at /_console/ on the same address. eval "$(doze-aws env)" sets up the shell you're in.

$ doze-aws
    endpoint  http://127.0.0.1:4566

$ eval "$(doze-aws env)"     # in another shell
$ aws s3 mb s3://receipts
make_bucket: receipts
Inside doze

Buckets and queues, in the same file as the app.

doze add aws, and in Larder, our made-up example project, doze names it aws.larder.doze and hands each service its address. The Python fulfilment service works through pick lists on SQS with boto3; doze AWS stays asleep until one of them calls.

# doze.hcl, from the Larder example
module aws "aws" {
  port = 4566

  bucket "product-images" {}
  bucket "receipts" { versioning = true }

  queue "pick-lists" {
    dlq          = "auto"
    max_receives = 5
  }
}

# and in the app that uses it
AWS_ENDPOINT_URL = module.aws.url
Honest by design

A fidelity ledger for every service.

An emulator that is too permissive is the dangerous kind: your code passes here and fails on deploy. So each service states what really works, and every refusal AWS's own service models state is checked in CI.

ServiceOperationsConstraint cases
DynamoDB27 of 27333 / 333
EventBridge40 of 40448 / 448
IAM89 of 93702 / 702
Lambda47 routed612 / 621

4 of 17 shown · the full ledger →

What it isn't, and what's not yet proven

  • Not checked against a live account yet. boto3 scenarios are written for every service; their recordings against real AWS are pending, and until they exist nothing here is called verified.
  • Not more forgiving than AWS, on purpose. If it accepts something AWS refuses, that is a bug worth reporting.
  • Not your cloud. No VPCs, custom domains or TLS termination: the operations that act on cloud infrastructure are declined, each with its reason.
  • Nothing sent anywhere. No outbound connections of its own, no account, no telemetry, nothing outside the data directory you name.

All of AWS. None of the account.

On its own, macOS or Linux
$ curl -fsSL https://raw.githubusercontent.com/doze-dev/doze-aws/main/install.sh | sh
In a doze stack
$ doze add aws
More ways, and doze itself: Download · Docs

doze AWS is not affiliated with Amazon Web Services. AWS and the service names are trademarks of Amazon.com, Inc. or its affiliates.

Part of the doze family. Works alone.

Three products, each its own download, each happy on its own. Together, doze runs the other two inside your stack and gives them names.