Feature Flags - Deploy Dark, Release When Ready

We got better at shipping code this year. Pipelines build, tests run, images land in the registry, and — if you bought into the GitOps story — the cluster eventually matches Git. That is deploy. What still bites us is treating deploy and release as the same button.

I spent the last couple of sprints putting Microsoft.FeatureManagement in front of a few half-finished ASP.NET Core endpoints. Not because flags are fashionable. Because product wanted a quiet soak with internal users, and ops wanted a kill switch that did not involve a Friday rollback train.

Read More

GitOps - Stop kubectl-apply-ing Your Way to Prod

Our deploy pipeline used to end with a job that ran kubectl apply -f against a folder of rendered YAML. It worked. Until it didn’t. Someone would fix a ConfigMap by hand at 11pm, forget to commit it, and three days later the next pipeline run would “helpfully” overwrite the fix. Or the opposite: Git said one thing, the cluster said another, and nobody could tell which was deliberate.

I have been watching the GitOps wave for a while — Flux from Weaveworks, Argo CD from the Intuit folks, now both under the CNCF umbrella. This week Argo CD shipped 2.0. That felt like a good moment to write down what actually changed in how I think about deploys.

Read More

After SolarWinds - Who Builds Your Binaries?

For most of my career, “supply chain” meant the warehouse people fretted about. Then SolarWinds happened. A signed Orion update carried a backdoor. Thousands of customers installed it because the signature looked fine and the vendor looked trusted. Suddenly the question was not only “is our code secure?” but “is the machine that builds our code secure?”

I spent a weekend walking our .NET services with that question in mind. Spoiler: we had strong opinions about TLS and JWT, and almost no opinions about NuGet restore on the build agent.

Read More

Correlation IDs - Following One Request Through the Noise

Last Tuesday I got a Slack ping at 9:40pm: “payments are slow, can you look?” I opened Kibana, typed status:500, and watched a waterfall of red. Five services. Three pods each. Everyone logging something useful. Nobody logging the same something. Twenty minutes later I still could not answer the only question that mattered — which user action started this mess?

That is the night I stopped treating correlation IDs as a nice-to-have and started treating them like a seatbelt.

Read More

Kubernetes Requests and Limits - Paying for Air

Our cloud bill went up again last month. Not because traffic exploded — traffic was fine. The cluster just… got fatter. More nodes. Same apps. Same user count. When I dug into it, the villain was not a runaway Deployment. It was a dozen YAML files where someone typed cpu: "2" and memory: 4Gi because that felt safe six months ago and nobody ever looked again.

Kubernetes will happily reserve capacity you never use. The scheduler only cares about requests. Your finance team only cares about the invoice. Those two facts meet in the middle as slack — resources booked, paid for, and idle.

Read More

WSL 2 - Finally a Real Linux Kernel on My Windows Laptop

Four months into full-time work from home, my living room table is the office, the standup room, and the lab. The corporate laptop still runs Windows because that is what Visual Studio, Outlook, and the VPN client expect. The services I actually ship, though, are Linux containers. For years that meant Hyper-V VMs, slow bind mounts, and a quiet acceptance that “it works on my machine” was a slightly different machine than production.

Windows 10 version 2004 shipped WSL 2 into general availability earlier this year, and Docker Desktop’s stable channel caught up with a WSL 2 backend in May. I spent a weekend moving my local .NET Core container workflow onto it. Not because I needed another toy — because the old setup was eating evenings I no longer have spare.

Read More