brew install tfswitch

tfswitch has had 86 versions and over 15 million downloads (see latest count below), and help is what got it there. I wrote it as a command-line tool that lets you switch between versions of Terraform.

Total Downloads

In 2018 I was in Chicago for the GOTO Conference. What I remember best is a long, chilly walk along the pier near Lake Michigan with Joe Armstrong, co-designer of Erlang and a pioneer of fault-tolerant systems. He talked about purpose, and reminded me that coding began as a way to help people, not just a way to make money.

Joseph Leslie Armstrong (27 December 1950 – 20 April 2019) was a computer scientist working in the area of fault-tolerant distributed systems. He is one of the co-designers of the Erlang programming language.

I left Chicago with those words in my ears and a very specific, very annoying problem.


At my previous company we lived on Terraform, which lets you build and manage large digital infrastructure through code. It moved too fast. Configuration that worked perfectly yesterday could be a headache today.

I first understood what a version mismatch costs on a Friday at 5 p.m. People were packing up. Someone was talking about drinks. Then the coworker who sat next to me pushed a Terraform change. I pulled the branch and ran terraform plan, and Terraform refused with an error that made me feel like I was the problem.

He’d used a newer, incompatible version. The code worked on his machine because his binary understood the new syntax and state expectations. Mine didn’t. Neither did our pipeline.

I thought this is going to be quick.

But, it wasn’t. Upgrading here broke something there. Fixing that revealed something else. Every attempt to just make it work multiplied the mess. The cause was tooling drift. By the time I got it working, I was the only person in the office.

I spent my Friday evening untangling a mismatch that wouldn’t have happened if switching Terraform versions were effortless.


So I wrote tfswitch. It does what the name says. If you don’t have a particular version of Terraform, it downloads it. Once it’s installed, you pick the version you need from a dropdown and get back to work.

Other tools did something similar. I wanted mine to be simple, to need minimal configuration, and to be dirt easy to install. The first version had about five features, on purpose. The community noticed almost immediately.

Getting strangers to trust a new tool turned out to be harder than building it, so I treated documentation like product. I made GIFs so users could see the tool working at once. I wrote copy-paste commands so the time to value was under ten seconds. I also wrote a blog post on Medium and mentioned it on Twitter a few times. Nothing fancy. Just enough to help the project exist outside my laptop.

Then tfswitch came up at HashiConf. A speaker named Fernanda Martins told the audience that if they were migrating to Terraform 0.12, they should use it. It was one tip in a talk about Terraform best practices, but it was on HashiCorp’s stage, and downloads spiked into the millions. I was now the sole gatekeeper of a tool used by thousands of companies.

After that it wasn’t just my side project. People were going to depend on it. More usage meant more bug reports and more edge cases, and many of them I couldn’t reproduce, because they happened on machines I’d never seen, with constraints I’d never considered. I couldn’t keep up alone, so I opened the doors. I let others contribute features and fixes. I still gatekept releases, and I built a comprehensive test suite to protect the project from accidental breakage.

Even so, the issues often outweighed the fixes. The contributors were good. What I needed was more of them, and a way for people to contribute even if they weren’t Go experts, without me holding their hand.

So I built what I called the “Help Me” pipeline: exhaustive, step-by-step guides on how to clone the repo, set up the environment, and contribute code. I wanted it so easy that a developer with a week of Go experience could feel like a hero contributor. It worked for a while. The project went from no contributors to 10 (50 today).

I asked a handful of contributors to help review and maintain the project. We considered Discord and ended up on Slack. We hooked GitHub notifications into the channel, so issues, PRs and discussions weren’t stuck in one person’s inbox. Most PRs needed at least two reviewers, and releases no longer depended on one person having a perfect weekend.

We also shortened the release cycle. Instead of waiting four weeks to ship fixes, we added checks and automation, and now we can release or roll back a version through GitHub with a single click.

I couldn’t have done this alone, and I want to name two people: George L. Yermulnik and Matthew John. I’ve never met either of them in person, yet they helped carry this project forward. George is from Ukraine and is the main person maintaining the software now. I hope I get to meet him someday.

Tagged in: