alembic dev log, june 2026
i’m starting a monthly note on what moved in alembic and the tools around it, published the first day of each month. this first issue is a baseline: where things stand at the end of june 2026, so from july on i can just report the delta. i’ll keep these short.
what alembic is
i’ve written and talked about alembic, but since then, almost 3 months have passed, and that’s about fourty-five years in alembic time, so let’s pretend this is a first unveil.
i’ve taken to calling alembic the connective tissue of your network automation pipeline or the edges between your boxes. what does this mean?
most systems in the network automation space are boxes. they are sources of truth, or orchestrators, or observability tools. those are important, but we tend to forget about the arrows between those boxes when we draw the diagram: how does data actually flow from one system to the next?
this is what alembic does. it’s the layer between the elements of your stack, the aether that flows between your components. and it speaks your own data model, not that of any vendor.
sounds pretty cool, right? i think so.
where it stands
cliff’s notes:
- alembic transforms data from a source of truth into a canonical, vendor-neutral ir, validates it, and converges that model onto one or more backends. it works on the edges between systems, not inside any one of them.
- latest release: 0.5.0, on crates.io
(
cargo install alembic-cli). - the loop is the same every time:
validate→import→map→plan→apply. pull, map, and plan are read-only;applyis the only step that writes, and it writes a deterministic plan you’ve already seen. mapis the powerhouse that transforms and shapes the data on the way.- i have case studies of migrations between ipam/dcim systems
(
infrahub<->netbox) and full pipelines (data->netbox->containerlab,ssh,prometheus,grafana). it just works.
the engine today
- map is a pure ir→ir transform layer: rules select
objects by type and predicate, reshape them through
${...}templates, rewire references across renames, and can call user-defined starlark transforms. it also doesgroup_byaggregation andlookupsacross refs. because it’s pure, maps chain. plan --reportprints a read-only drift report (changed / missing / extra) without writing anything.- apply is deterministic and topologically ordered; deletes stay gated
behind
--allow-delete. - state lives in a local
state.jsonor postgres, mapping stable uids to backend ids so renames don’t churn.
adapters
- open core, in the repo: netbox, nautobot, infrahub (read + write), generic rest, peeringdb (read-only), and django (emit) if you want your own dcim api.
- commercial ops layer (alembic-ops): emitters that carry the same ir out to ansible, nornir, dns, prometheus, ssh, containerlab, and graphviz/mermaid diagrams. it’s a separate, paid layer, so i’ll only mention it here where it touches the open core1.
- extension: any of the above can also be an
external adapter, a process alembic spawns that speaks json
over stdio (protocol version 1). this month i shipped two front doors
for writing one: a python sdk (
alembic-adapter-sdk) and a rust template repo. and to prove that it works, i wrote a full adapter in carp, a programming language i co-maintain, in less than 250 lines of code.
people
one professional contributor works on alembic alongside me, and we’re onboarding two more. yes, people get paid to work on alembic.
erik
svedäng works across the engine and the ops layer. he built
the journal-backed resumable apply: an apply that dies
partway through resumes from where it stopped instead of redoing its
writes, alongside a run of correctness and performance fixes (including
turning an o(n²) path into o(n)). in the ops layer he wrote the
containerlab connector and “erratic”, a fault-injection adapter whose
whole job is to make the resumable-apply machinery prove itself.
health
- june was the biggest month so far: 0.4.0 and
0.5.0 both shipped. 0.4.0 retired the old raw-yaml→ir
compiler and replaced it with
map; 0.5.0 taught the netbox adapter to handle generic foreign keys in both directions (a breaking change to a few ir field names). - the “one source, many artifacts” fabric pipeline runs as a
golden-file e2e in ci: it boots a real netbox, runs
seed → import → map → emit, and diffs every generated file against a committed baseline. that’s the regression net behind the claim that one model feeds every tool.
on deck
- public demos, case studies, and war stories are being prepared as we speak!
- from the unreleased changelog: format validation for
cidr/prefix/mac/slugfields, stricter checks that schemareftargets name a real type, andmaprewiring references nested insidelist/mapfields. - more reference external adapters, now that the two sdks make them cheap to write.
next issue at the end of july.
the split is deliberate: the ir, the engine, and the dcim/ipam connectors are open source under apache-2.0; the fabric and ops connectors are where the commercial side lives.↩︎