All articles

Infrastructure / Swamp & agents

I Asked Swamp to Turn My Linux VM Process into a Windows One

A working Linux VM process, a Windows conversion, and the checks and human handoffs that made it repeatable.

Three connected vessels in a purple-lit workshop, with green and amber conduits.
Original artwork from the published blog.

I had a working process for building Linux VMs on a three-node Hyper-V cluster. I’d used AI to help with the scripting, tested it, and used it for real builds.

Then I started looking at Swamp. I pointed it at the original script and process and asked it to do the same job for Windows VMs, accounting for the differences.

The conversion took about a minute and a half. The first test pass was mostly clean. Image capture, boot testing, and further checks followed as I worked through the Windows path.

That was enough to make me look more closely at what I could reuse.

What I gave it

I already had the build process and the decisions behind it: the VM roster, resource sizes, networking, cluster placement, and checks around the build.

The Windows version needed to preserve that intent while handling a different operating system. Linux used a cloud image and cloud-init. Windows used a sysprepped golden image, an answer file, and configuration steps for things like disk expansion and domain membership.

Swamp became the place that held the roster and rendered the scripts and data files. Changes started there, then I rendered a new copy for the cluster node. Editing the copy on the node would leave me with two versions of the truth.

Where I still did the work

There was a fairly important limitation: Swamp on my Mac couldn’t reach the hosts in the other datacenter.

I copied the rendered files through the remote-desktop gateway and ran the scripts on the cluster node myself. Swamp held the plan, but I was still carrying it across the network boundary.

Before running anything, I compared the copied files with the rendered versions using normalized hashes, character counts, and line counts. Then came the preflight, build, status, and configuration checks.

The workflow included approval gates for the parts I had to complete outside Swamp. That made the handoffs visible instead of treating a generated script as a finished build.

What needed tightening

The problems that showed up were ordinary operational ones.

A copy-and-paste added a stray character to the end of a script. An older copy from a synced folder could look like the right file. Those were good reasons to keep checking what actually reached the node.

The Windows path also needed to account for the cluster placing a VM on a different host. Configuration had to reach the VM’s owner node rather than assume it was still on the node where I started.

There was even a reporting bug that said “WORKGROUP joined” when the domain join had succeeded. The operation worked, but the output gave me the wrong answer.

I kept feeding those findings back into the scripts. After confirming image capture and boot, I added more dynamic DNS checks, Windows activation checks, preflight and what-if options, and clearer success and failure output.

Each check needed to tell me whether it was safe to continue and, if something failed, where to look.

Where I kept approval

The same approach applied to recording addresses in NetBox.

Swamp checked the proposed changes against the existing data and wrote them into a branch. I reviewed and merged that branch myself. The workflow then checked that the expected records were actually present in the main data.

That last check mattered. In the NetBox workflow I was using, a merge without the Commit checkbox was only a dry run. Getting through the interface wasn’t enough to prove the records had changed.

What I took from it

Starting with a working Linux process gave the Windows conversion something concrete to build on. I supplied the existing work, chose the next target, ran the tests, and used the results to improve the process.

The next step is giving a Swamp worker a network path to the hosts so it can run more of those steps directly. That remains proposed work.

For now, I have a repeatable process for both operating systems, with a clear place to make changes and clear checks before moving on. The quick conversion got me started. Running it against real infrastructure made it useful.

Interactive companion

What survives the handoff?

A small teaching model of the checks in this article. See why “generated” is different from “verified.” It does not run Swamp or touch infrastructure.

The OS choice illustrates the different source inputs. The VM handoff checks and outcomes are shared by both targets. The NetBox example is a separate address-record workflow with its own stages.

The interactive controls are unavailable until they load. Read the workflow and open “Read the model without interacting” for every scenario.

Context: VM files cross a network boundary through a human handoff. The OS choice changes only the illustrated source inputs.

Windows input: sysprepped golden image + answer file.

  1. 01RenderSwampPlan and files
  2. 02Carry & compareHuman handoffCopied file checks
  3. 03Run & checkHuman on nodePreflight, build, configure
  4. 04VerifyObserved resultCheck actual state
Start with the actual boundary.

In the article, Swamp on the Mac could not reach the datacenter hosts. Jason copied the rendered files, compared them, then ran the scripts on the cluster node. A worker with a network path is proposed work.

Read the model without interacting

Linux: cloud image + cloud-init. Windows: sysprepped golden image + answer file. Both preserve the intended roster, resource sizes, networking, and placement; the model does not simulate an operating system.

  • Changed copy: stop at the file comparison. Check the copied artifact before execution.
  • Changed owner: configuration must reach the VM’s current owner node. A remembered node is not enough.
  • Separate NetBox workflow — dry-run merge: Swamp checked proposed address changes against existing data and wrote a branch. Jason reviewed and merged it. The workflow checked for the expected records in main. Without Commit, a merge was only a dry run. These are separate stages, not the final step of VM execution.
  • Clean path: proceed only under the model’s stated assumption that checks succeed. This is not evidence that a real build is safe.

The four stages simplify the account for explanation. They are not the exact Swamp workflow graph, and these are illustrative states, not measurements.

Questions or a different perspective?

LinkedIn follow-up
Back to all articles