Diem CMF .NET Lab
Anything-as-code. You better make it a module.
I am building an ecosystem of reusable C# tools that wrap the tools I already use: command-line binaries, configuration formats, VM provisioning, container engines and routing. Their commands and configuration become types I can discover, compose and refactor in my IDE, with autocompletion.
The destination is a reproducible HomeLab I can describe and control from a C# project. C# is the language for describing the instance: its machines, services, configuration and operations become a typed model with IDE completion and compiler feedback. The existing modules supply the building blocks; their complete integration remains under development.
This is the same Anything-as-Code principle that drives Requirements-as-Code. Requirements-as-Code applies it to software intent and verification; Diem extends it to application models and their development environment. The HomeLab is the integration target where those infrastructure modules can be composed and exercised together.
From Tools to a Lab
Problem. A development platform spans Packer templates, Vagrant boxes, Docker hosts, Compose services, routing and build tools. Each integration brings its own commands, configuration and lifecycle.
My contribution. I turn recurring integrations into C# modules: typed binary wrappers, configuration Bundles, generators and infrastructure contributors. A project can compose these modules and supply its own settings and behavior.
Result so far. The FrenchExDev repository contains reusable command APIs, configuration models and VM orchestration code. I am developing the composition layer that will connect them to the lifecycle of a Diem Lab instance. The goal is a repeatable path from a C# description through generated configuration and orchestration to running infrastructure; the full path remains an integration target.
Typed Commands and Serializable Bundles
Two complementary mechanisms bring existing tools into C#:
| Mechanism | What I describe in C# | What it connects to |
|---|---|---|
| Binary wrapper | Commands, arguments, options and execution results | An existing executable such as Packer, Vagrant, Docker, Docker Compose or Git |
| Bundle | Configuration models, service definitions and generated files | The formats consumed by tools, including Compose configuration, Traefik YAML/JSON and Packer HCL2 |
BinaryWrapper collects CLI help into versioned command descriptions. Roslyn generators use those descriptions to produce C# command types, builders and clients. The IDE exposes the available members; execution still goes through the underlying tool. See the BinaryWrapper implementation (ouvre dans une nouvelle fenêtre).
Bundles make configuration reusable and serializable. The Compose and Traefik design pipelines download versioned schemas and generate typed models. Traefik provides YAML/JSON serialization, while the Packer Bundle writer materializes HCL2 and companion files. Configuration, command construction and execution can therefore share one C# project. Compose (ouvre dans une nouvelle fenêtre), Traefik (ouvre dans une nouvelle fenêtre), Packer (ouvre dans une nouvelle fenêtre).
The ecosystem also includes Wrapper.Versioning, a reusable pipeline for discovering versions, downloading artifacts and transforming them. For the Lab, the goal is to resolve reusable Bundles and their versioned artifacts as project dependencies, then compose the instance from their C# contracts. Versioning pipeline (ouvre dans une nouvelle fenêtre).
A Lab Instance as a C# Project
The intended workflow starts with a C# project representing my instance of the Lab. I reference the modules I need, describe the infrastructure and services, and implement project-specific operations using their typed APIs.
- Describe the instance. Declare the project's machines, hosts, services, routes and configuration, with IDE completion and ordinary C# composition.
- Build VM images. Use Packer and image contributors to prepare reusable images and Vagrant boxes.
- Run the VMs. Use Vagrant and Vos to provision machines and manage their lifecycle, including VMs that run Docker engines.
- Select the Docker host. Manage multiple Docker hosts across those VMs, and select or switch the Docker context associated with the current project's operation.
- Compose the services. Generate configuration, operate containers through Docker Compose and configure their routes through Traefik.
- Control the current project. Connect start, stop, rebuild, status and diagnostic operations to the resources described by that Lab instance.
The model binds an operation to a project, a target VM or Docker host, and the relevant services. Describing an instance and applying its configuration are separate steps in this workflow.
Building Blocks Already in the Repository
| Building block | Concrete implementation |
|---|---|
| Typed CLI integration | BinaryWrapper (ouvre dans une nouvelle fenêtre) and consumers for Docker, Compose, Packer, Vagrant, Podman, Git and the GitLab CLI |
| Image and VM lifecycle | Packer (ouvre dans une nouvelle fenêtre) models and writers, plus a Vos Vagrant backend (ouvre dans une nouvelle fenêtre) that invokes typed Vagrant and Packer commands |
| Composable Docker hosts | Vos.Alpine.DockerHost (ouvre dans une nouvelle fenêtre) contributes Docker provisioning, shared folders and variables to an Alpine VM model |
| Typed configuration | DockerCompose.Bundle (ouvre dans une nouvelle fenêtre) and Traefik.Bundle (ouvre dans une nouvelle fenêtre), with schema-driven generation |
| Reusable foundations | Result (ouvre dans une nouvelle fenêtre), Builder (ouvre dans une nouvelle fenêtre) and Wrapper.Versioning (ouvre dans une nouvelle fenêtre) support composition across integrations |
An existing contributor illustrates the approach: describe a Docker host using a reusable machine type, then extend it for the current project.
using FrenchExDev.Net.Vos;
using FrenchExDev.Net.Vos.Config;
using FrenchExDev.Net.Vos.Alpine.DockerHost;
var machine = new VosMachineType();
new DockerHostContributor().Contribute(machine);
machine.SharedFolders.Add(new VosSharedFolder
{
HostPath = "./project",
GuestPath = "/workspace"
});using FrenchExDev.Net.Vos;
using FrenchExDev.Net.Vos.Config;
using FrenchExDev.Net.Vos.Alpine.DockerHost;
var machine = new VosMachineType();
new DockerHostContributor().Contribute(machine);
machine.SharedFolders.Add(new VosSharedFolder
{
HostPath = "./project",
GuestPath = "/workspace"
});This composes a VM configuration. The lifecycle backend applies it. The contributor source (ouvre dans une nouvelle fenêtre) shows how the Docker layer extends the Alpine module.
How the Lab Fits into Diem
Diem CMF .NET aims to connect application modeling, generated administration, frontend composition and an integrated Lab. The tooling ecosystem supplies the reusable infrastructure capabilities that this Lab will coordinate for application instances and workspaces.
The Lab is a required part of the proposed product; its exposure, access and security are configurable. A small instance can compose a few modules, while a larger one can describe several VMs, Docker hosts and service stacks.
The Diem documentation series develops this through product experience, architecture and technical specifications. The self-describing Lab explains how the same modules could describe and operate the Lab's own services.
Current Development and Next Steps
The ecosystem is growing through both new integrations and improvements to existing modules. Current local work includes a dotnet CLI wrapper built on BinaryWrapper and additional Compose schema versions. These local additions are separate from the public develop snapshot linked above.
The next composition work is the Lab instance model and its orchestration, including project-specific Docker context selection and coordination across VM and container lifecycles. Kubernetes is a planned integration, extending the same C# module approach to cluster resources and deployment operations.
The full Diem Lab remains under development. The HomeLab orchestrator documentation (ouvre dans une nouvelle fenêtre) still identifies it as design/specification work; the existing wrappers and infrastructure modules provide its building blocks. The HomeLab roadmap orders the integration work and later platform capabilities by dependency.
Source review: 9 September 2026, public develop at b467df3 (ouvre dans une nouvelle fenêtre), cross-checked with the local _i2 checkout. Implementation references describe inspected source; runtime validation remains specific to each component and environment.
Explore the FrenchExDev ecosystem · Back to selected work · All projects