As Configuration
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.