mayfly

Ephemeral environments.
Delightfully fast.

One YAML spec spins up a test environment in an isolated Kubernetes namespace: an emulated AWS harness — S3, RDS, ElastiCache, Kafka, DynamoDB — plus your apps, wired up through real AWS APIs.

Spin up. Test. Tear down. A TTL reaper destroys anything left behind.

lives fast. gone by sunset.
$ mayfly up env.yaml
mayfly 0.1.6 · ephemeral by design
namespace merry-blonde-stoat created 0.3s
postgres (appdb) ready 5432 1.1s
redis ready 6379 1.2s
kafka (msk) ready 9092 2.1s
s3 (emulated) ready 4566 2.3s
api (your app) deployed 8080 4.8s
Environment ready in 6.2s · ttl 8h · gone by sunset
Namespace: merry-blonde-stoat
Endpoints written to Kubernetes Secrets
$

One spec, full stack

Declare S3 buckets, RDS databases, ElastiCache, Kafka topics, and app deployments in one YAML file. An in-cluster AWS emulator plays the cloud — your apps can't tell. Everything spins up together. Everything tears down together.

Truly isolated

Each environment is one Kubernetes namespace, deterministically named from a seed. Teardown is namespace deletion — no leftovers, ever.

Self-cleaning

TTLs on everything. mayfly reap and the reaper delete expired environments automatically. Live fast, clean fast. Leave no trace.

/ how it works

apiVersion: mayfly/v1alpha1
seed: pr-1234 # env name derives from this
ttl: 8h # reaped after this
emulator:
kind: ministack
services:
s3:
buckets: [assets, uploads]
rds:
- name: appdb
engine: postgres
dbName: app
elasticache:
- name: cache-a
msk:
- name: events
topics: [orders]
apps:
api:
image: ghcr.io/acme/api:pr-1234
port: 3000
secrets: [rds-appdb, elasticache-cache-a]

> Local emulation, cloud-compatible

AWS-compatible emulator running in-cluster behind http://aws:4566. Swap it out if you like. Your apps don't care.

> No Docker socket. No privileged pods.

We don't mount your Docker socket.
We don't need privileged pods.
We don't touch real AWS.
Sleep well.

> Secrets as the contract

Every service's endpoints and credentials are delivered as Kubernetes Secrets. Your apps consume Secrets. That's it.

> Deterministic naming

Names derived from the seed.
Predictable, shareable, scriptable.
Perfect for PRs and previews.

/ cli reference

mayfly up env.yaml
Create or update the environment from a spec (--seed/--set for per-PR variants)
mayfly status env.yaml
Pods + provisioned secrets
mayfly list
All mayfly environments, age + TTL
mayfly render env.yaml
Print the resolved plan, touch nothing
mayfly extend env.yaml --ttl 4h
Push expiry out
mayfly restart env.yaml
Rolling-restart apps (after re-pushing the same tag)
mayfly down env.yaml
Teardown now (namespace delete)
mayfly reap
Delete every expired environment

/ install

Requires: kubectl + any Kubernetes cluster (k3d is plenty).

$ uv pip install mayfly-cli
$ mayfly --version
mayfly 0.1.6

Or: pip install mayfly-cli