Skip to Content

CMDB-Kit

How the Schema Was Designed

I started with a flat schema and a lot of confidence. Every CMDB I'd seen used one set of types for everything, so that's what I built. All products lived in one hierarchy. Tags told you which product a CI belonged to.

It lasted about a month.

The tags fell apart first

The first product was a platform with firmware, hardware models, and physical gateways. The second was a software suite with VMs, disk images, and content filters. The third was a media gateway with codecs and session controllers.

I tried putting all of their components in one Component Type lookup. Firmware next to Codec next to Hypervisor next to Content Filter. It was gibberish. Every query pulled back a mix of unrelated things from different products. I added tag filters to the dashboards, but the filters had to go on every single query, every report, every automation rule. The first time someone forgot a filter on a scheduled report, it went to the program manager with three products' worth of servers mixed together. That was a bad morning.

So I gave each product its own branch in the schema. Its own Server type, its own Component type, its own Feature type. The prefixes (like CR, AN, SS) scoped every query automatically. The schema got bigger, but the data got clean. No more filter tricks. No more cross-product noise.

Then the sites got complicated

I had one Deployment record per site. Version number, status, done. Simple.

Then I learned that the same customer was running all three products. Product 1 was at version 3.2, supported by Team Alpha, scheduled for an upgrade in March. Product 2 was at version 1.1, supported by Team Bravo, no upgrade planned. Product 3 was still in the planning phase, no deployment yet. One record couldn't hold all of that without turning into a spreadsheet with product-specific columns that were blank for two out of three products.

I split it into two records. A Site is just a name, a shared identity for the customer. A Deployment Site is everything about one product at that customer: version, team, schedule, status. One Site, multiple Deployment Sites. Each product gets its own deployment record without polluting the others.

Some sites also had deployments spread across multiple buildings and mobile units. Site Location Assignments handled that: one Deployment Site linked to multiple physical locations.

Not every site gets the same features

This one surprised me. I assumed every site running a product got the same product. They didn't. Some sites ran the product on a single network. Others ran it across multiple classification domains with different features enabled on each side. A site might get features 1 through 5 on one network and only 1 and 3 on a restricted network because of security requirements or contract scope.

The Deployment Site needed to track which features were active at that specific site, on which networks, with which restrictions. No process-centric or infrastructure-centric CMDB handles this. They can tell you what servers exist. They can't tell you which features are deployed where.

The auditor question

An auditor asked me to prove that every requirement allocated to a release was actually implemented and tested. I had Features. I had Product Versions. But nothing that said "this feature was delivered in this version, and here's the evidence."

I added Feature Implementation as an immutable audit record. It links a Feature to a Product Version with a status. Once you mark it implemented, the record freezes. You can trace from a requirement through to what shipped and where it went. Requirement to Feature to Feature Implementation to Product Version to Deployment Site.

It became the most-queried type in the schema. Engineers and program managers asked the same thing every day: "is this feature in this release?" One query, always.

Baselines seemed like overhead until they weren't

I resisted baselines. The schema tracked current state. Why freeze a snapshot when everything was already in the CMDB?

Then someone asked what the approved configuration looked like six months ago, at the time of the design review. Without baselines, I spent two days digging through email, meeting notes, and version control history trying to reconstruct what the system looked like at that point in time. With baselines, it would have been one query.

I added three baseline types. Functional Baseline captures the approved design. Allocated Baseline captures the requirements allocation to components. Product Baseline captures the approved build. Each one freezes a different aspect of the configuration at a point in time. Now when someone asks what the approved state was at any milestone, the answer is immediate.

Shipping software to classified sites

The release wasn't just a version number. It was a set of physical media files that had to be built, verified, stored, and shipped to deployment sites. For air-gapped environments, that meant burning encrypted DVDs, packaging them with distribution letters and decryption instructions, and physically delivering them to secure facilities.

I needed to track which media was prepared, how it was encrypted, who shipped it, who received it, and whether installation was verified. The Distribution Log tracks that entire chain of custody. Product Media tracks individual files with checksums. Product Suite bundles them into versioned packages.

No commercial CMDB has anything like this. It's a pattern from formal configuration management practice that the platforms just don't model.

Shared infrastructure needed a home

The three products shared CI/CD pipelines, monitoring, development tools, and build servers. Putting that infrastructure under one product's prefix made it look like that product owned it. Leaving it unscoped meant it had no home and showed up in every product's queries as noise.

A Shared Services branch with its own prefix solved it. The shared infrastructure has its own Server, Network Segment, and other types. It serves all products equally and doesn't pretend to belong to any single one.

What I learned

Every one of these changes came from something breaking. I didn't sit down with a standards document and design the perfect schema. I built what I thought would work, watched it fail, and fixed it. Seven times.

After the schema stabilized, I mapped it to the formal standards: ITIL 4, EIA-649C, MIL-HDBK-61B, ISO 20000. Every decision I'd made from operational necessity aligned with what those standards prescribe. The standards validated the design. They didn't drive it.

CMDB-Kit is a sanitized, generalized version of that production system. The example data uses a fictional SaaS CRM instead of the real products, but the structure, the relationships, and the patterns are the same ones that survived production use.

Try It

The schema, adapters, documentation, and example data are open source.