As Configuration

Posted on Mar 7, 2025

Mitchell Hashimoto post As Code this week reflecting on what "as code" means to him. Different from the popular interpretation of being literal code, his view is that the "code" in "as code" is a 'system of principles or rules", like a "code of ethics". The poor guy has probably been the target of angry emails for a decade.

My experience in the Infrastructure-as-Code world has been that a lot of people do take the "as code" a little too literally. Usually it’s being strict about workflows, like dogmatically insisting we should do apply-after-merge because that’s closer to the workflow for application code. While I don’t 100% buy Mitchell’s post, Terraform is clearly trying to make infrastructure management more like a programming experience, I agree with the sentiment.

In my opinion, one of the bigger negatives of "as code" when it comes to infrastructure, is that, whether or not one wants to consider it code, it is clearly distinctly and meaningfully different from application code.

When it comes to IaC, there is no artifact that we can create, and keep on creating, and move around environments, to run and test, like application code. The end result of IaC is the infrastructure and that infrastructure can only exist once and every time we apply the change, the old infrastructure is gone. Infrastructure is a physical thing. The dev environment and prod environments will never be the same. There is no artifact we could make in our dev environment and then move over to prod once its validated. We can only make a dev environment that looks a lot like our prod environment and hope the differences are negligible.

In this way, Infrastructure-as-Code is more like Infrastructure-as-Configuration. The cloud is a big application that we’re configuring via Terraform code. When we apply, we are changing the configuration. You could achieve the same result by writing a program that takes a YAML file and uses awscli to make sure the infrastructure matches it. Terraform is a complex computational engine whose purpose is to produce a static configuration. We never directly see it, it’s not written to a file, but conceptually that is what is happening.

A lot of the application code workflows that we translate to infrastructure code are a bit like square pegs and round holes. The product I develop, Terrateam, leans heavily into managing infrastructure like code. We have to break the illusion by using pull request comments to operate the software (to perform an apply you comment in the pull request terrateam apply). Terrateam supports workflows that do not require commenting but, because infrastructure is a physical thing, you might have to force an apply or a plan to re-run due to no fault of the code but because there was a network hiccup, or an API rate limit hit, or some data didn’t exist yet, which forces a re-run.

And that’s OK. Despite Infrastructure as Code being an imperfect analogy, it’s a really useful analogy. It lets us accomplish a lot using workflows that are familiar. Tools like Terrateam guide us through the places where those workflows do not work exactly like we are used to in our application code. It’s just a lot easier to open up a pull request to make an infrastructure change than learn another piece of software.