01 The problem

Infrastructure one person understood

During a round of budget cuts our DevOps engineer left. He was the only person who knew which servers we ran, which domains pointed where, how the proxies were wired and who still had access. For two months every change started with detective work.

The estate was small but awkward: twenty to thirty machines across several providers, no cluster, some servers in Hetzner because it is cheaper and some inside Russia because the service has to stay reachable there, more than a hundred domains, and proxy chains crossing borders. Hiring meant a search, onboarding and budget we did not have. Not hiring meant keeping the risk.

02 The decision

A model of the system, not a server list

It started as what looked like a one-off chore: list the machines. The first input was literally screenshots of the Hetzner and AWS consoles, which an agent transcribed into JSON. There was no upfront schema; the structure grew with each urgent question.

Every new concern became another layer in the same file. A registry of SSH keys with aliases showed who could actually log in, and turned up about ten keys that should not have been there. Hardware specs exposed machines we were paying for but did not need at that size. Container lists showed what really ran on each node. Domains gained labels for role, environment, priority and audience region — the last one matters because a Russian user should not hit a foreign IP and a foreign client should not see a Russian footprint. A TLS check records the issuer and expiry of every certificate, including whether older Android devices still get an RSA one.

Two choices made it hold. First, instead of letting the agent regenerate the same collection code on every run, we had it write each script once, stored it and ran it directly: fewer tokens, and data collected the same way every time. Second, we started describing the expected state, not just facts. A well-configured reference server became a monitoring standard with required components and an acceptance checklist, and every machine got a coverage status. Backups followed the same pattern: destinations, policies and the latest observations.

03 The outcome

Ten thousand lines under version control

Three weeks later the inventory was close to 10,000 lines. It lives in Git, refreshes with a short command, and backup checks run daily from GitLab CI. Infrastructure work now leaves a commit behind: a link is enough for a colleague to see what changed, and changes to the repository post to Telegram.

The bigger win was a single source of truth that new checks and tools can be built around cheaply. Switching tools proved the point — when I moved from Codex to Claude Code, the new agent read the structure and carried on where the old one had stopped.

04 Takeaways

What I would carry into the next project

The agents did not replace an engineer; they sped up work that would otherwise have been done by hand. The durable value is the data model: while the structure stays stable, it can take on new jobs without rewriting what is already there.

The approach has a boundary. Enterprises and heavily regulated systems still call for Terraform, Ansible, Kubernetes and a proper platform team. For a startup that needs speed, repeatability and a small budget, a living inventory buys control without a hire — a compromise that worked for us.