robert@notes: ~ — zsh
➜ robert@notes ~ git:(master) cat ~/.motd
Robert's notes - Notes on Go, Kubernetes, Terraform/OpenTofu, AWS and DevOps culture.
➜ robert@notes ~ git:(master) ls ~
➜ robert@notes ~ git:(master) ls -t posts/ | head -n 5 | xargs head -n 3

Go modules and packages: how to create a module and how to split an app into packages

Programming GoLang

Every Go project starts the same way: one main.go, it works, it grows, and at some point you have a 1500-line file and the question “how do I split this up” - followed by “and what is the difference between a module and a package again”. This post is the answer I give every time. It is short on theory and long on the three commands and one directory layout you actually need, with links to the official docs for the parts I skip.

read more →

One module block, every region: provider for_each in OpenTofu

Here is a thing I wish somebody had shown me the week OpenTofu 1.9 came out. If you have ever had to deploy the same stack to five AWS regions, you know the ritual: five provider "aws" blocks with five aliases, five copies of the module block differing only in the providers map, and a bad feeling every time a sixth region shows up. In OpenTofu you can put for_each on the provider block itself. One provider block, one module block, regions come from a variable. Terraform still cannot do this.

read more →

I turned this blog into a terminal window (and threw out the theme while I was at it)

Meta CSS Jekyll Web

So, new look. If you were here before you probably remember a white page with a serif font that looked like every other Jekyll blog from 2016 - because that is exactly what it was. I have wanted something that looks like the thing I stare at all day for a long time, and last evening I finally did it. This is a short note on how, mostly because I ended up deleting more than I added, and that part surprised me.

read more →

Claude Code skills - teach the agent your workflow once, in a Markdown file

Every time I opened Claude Code I was typing the same paragraph: “new post goes to _posts, file name starts with the date, front matter looks like this, build to a temp dir, don’t touch docs/”. Then I discovered that this paragraph has a proper home. It is called a skill, it is one Markdown file, and the agent loads it on its own when the task matches. This post is the five minute version: what a skill is, where it lives, and two examples worth copying.

read more →

Route 53 Resolver DNS Firewall blocklist with OpenTofu - full example

In the previous post I compared the options for blocking egress to specific domains from an EKS cluster, and concluded that Route 53 Resolver DNS Firewall is the cheapest seatbelt you can put on a VPC. Talk is cheap though, so here is the whole thing as working OpenTofu code: a custom blocklist, the rule group, the VPC association, fail-mode configuration and query logging so you can actually see what gets blocked. Tested with OpenTofu 1.12.

read more →
➜ robert@notes ~ git:(master) ls -t posts/ | sed -n