← Back to the notebook

The Edge Box Should Be Cattle, Not Pets

There is a moment in every edge project where you have to decide what a device is. Is it a pet you raised? You SSH in, apt install a few things, tweak a config until data flows, and now that box is special. Or is it cattle? One of a herd, interchangeable, built from an image, and if it dies you flash another and it comes up identical.

For a fleet of gateways sitting in plants I will probably never visit, it has to be cattle. This week that stopped being a slogan and became a build pipeline. The interesting part was not the idea. It was how many small, dumb things sit between "I have a good idea" and "the image actually boots green."

The plan is a golden image. OS, edge agent, and the OTA public key all baked in, produced by a repeatable build instead of by a person logging into each Pi. Flash it, boot it. The agent sees it is unclaimed and serves a console on the local network. You enter a short-lived claim token and it enrolls into the fleet. Zero to data with nobody typing sudo on the floor. That is the shape. It is right. It is also where the honest part starts.

The constraint is that a golden-image build is a compiler for a whole computer, and compilers fail in boring ways. Building an arm64 image on an x86 machine means emulation, and emulation only works if the emulator is installed. Miss qemu-user-static and the build just cannot find the aarch64 binary and dies partway through. Pin the build to a moving upstream tag and it breaks the week upstream reorganizes. Pinning to a stable release instead of master was not a nice-to-have. It was the difference between a reproducible build and a coin flip. A stage that fetches a release asset that does not exist. A relative deploy path that sends the finished image nowhere, so the build "succeeds" and produces nothing you can find. None of that is architecture. All of it is the actual work.

What I would check, doing this again: does the build produce the same image from a clean checkout, on a machine that has never seen the project? That is the real test of cattle-not-pets. If the image only builds on the one laptop where you slowly got it working, you do not have a golden image. You have a pet with extra steps.

The surprise, every time, is how much of "infrastructure as code" is really "infrastructure as debugging someone else's build tool." The design decision took an afternoon to settle. Reproducible image, no remote-login surface, config pushed from the cloud instead of typed on the box. Getting the emulator, the pin, the asset fetch, and the deploy path all correct at once took longer, and there was nothing clever about it. It was just refusing to hand-fix the box.

Notes for next time: decide cattle or pets before you touch the first device, because it changes everything downstream. How you claim, how you configure, how you recover. Bake identity and trust into the image, not into a post-install script someone has to remember to run. Pin every upstream to something that does not move under you. And treat the first clean flash on hardware you did not build the image on as the real milestone. Everything before that is a demo.

← Back to the notebook