The Consulting CTO

Fenna 2

Almost exactly 3 years ago today, I released fenna, a thin Terraform wrapper built around a set of conventions for how to set up a Terraform project for a small team. My goal was to stay as close to vanilla Terraform as possible while simplifying state management within a team. And largely I succeeded. While the script hasn’t exactly set the world on fire with its popularity (not that that was my expectation or objective), I’ve been using it on projects small and large for the past 3 years. Along the way, I’ve encountered a few rough edges.

I was never entirely happy with the “sandbox” convention. “Sandbox” has always felt overly specific to me, and it made fenna less than a natural fit for simpler projects where you’re only targeting a single environment with no CI/CD and no team. I have several of those, mostly simple websites hosted on S3 with CloudFront (including this one) as well as global infrastructure within larger projects (such as remote state).


In version 2 of fenna, I’ve replaced the “sandbox” convention with the more general concept of a “target”.


Each target has its own profile, suffix, backend, and .terraform directory. In simple cases, you would only have a single target. Or in more typical usage, dev, stage, and (gasp) prod. But you could define finer-grained targets as well depending on how many backends you have. (And, yes, this also makes it easier to “do it live” with fenna for those situations where CI/CD doesn’t make as much sense.)


Targets are shared across developers via the repo by default, but each developer will still have to configure a target based off their own profile and suffix. The suffix can be blank if it’s not needed.

As with the sandbox in version 1 of fenna, you can customize per target using a .tfvars file matching the name of the target as well as per developer with user.tfvars. In version 2, I’ve extended this to add ${target}.sensitive.tfvars for injecting secrets into a plan. I’ve deliberately remained agnostic on how secrets are stored and shared—for example, with some additional scripting you could generate the sensitive file on the fly from a central secrets manager. sensitive files are in .gitignore by default (and I strongly recommend you keep it that way).

Unfortunately, fenna-specific .tfvars files have to exist in your working directory for fenna to work, even if they’re blank. Terraform’s CLI errors out if a specified file is missing. Personally, I’d prefer it to silently ignore the missing file, but alas.

If you happen to already be using version 1 of fenna and want to move to version 2, after updating your script, use fenna migrate to convert your existing .fenna directory to v2. Backups of both .fenna and .terraform are made in the process in case something goes awry. Your sandbox will be converted to just another target automatically.

And if you’re happily using version 1 and don’t feel like dealing with any of this, everything will continue to just work.

I’ve left the original scripts intact so that a Homebrew update doesn’t derail whatever you’re working on. I always find it irritating when I update software and then have to spend half an hour digging through changelogs to figure out what change broke the code that was working perfectly well before. (Hugo, I’m looking in your direction.)

In any case, check out version 2 of fenna.

Get the latest posts from The Consulting CTO