Everybody uses the GUI.

There’s nothing wrong with this. The GUI can be a very clean and intuitive way to interact with a piece of software. But there’s a price.

GUIs are terrible for automation.

If you’ve ever wanted to automate some Windows program, you know exactly what I’m talking about. There’s simply no good way to do it, and all the solutions available put you at the mercy of minor display changes in the GUI.

We invented APIs specifically to solve this sort of problem. If you want to let a machine do something, you give it a clearly-defined interface that doesn’t change (or that changes in clearly-defined ways at specific times).

Infrastructure as code (IaC) is simply taking advantage of APIs to automate your infrastructure management.

GUI-World

Imagine with me a world where everything you build is done by hand. No command line, no terminals, just point-and-click interfaces for all of it:

  • New server? Click-click-click.
  • Install new software? Click-click-click.
  • Move a file to the server? Click-draaaaag-click.

Sounds awful, doesn’t it?

Can you imagine trying to set up 10 identical servers that way? 20? 50?

Are you positive that you’d get everything 100% the same between all of them? I’m not, and I’ve been doing this for over a decade.

How long will it take you to do by hand?

Even in this modern world of GUI-everything, we still keep around the CLI because it gives us benefits that a GUI simply can’t match. IaC gives us those same benefits, but brings it’s own to the table as well.

Reproducibility

Want another copy of the exact same infrastructure? Just copy the IaC files (or use a module, D.R.Y.!) and tweak the incidentals (names, tags, server count, etc.).

You want to take an existing project and add something new? Just add the new resource code and re-apply it.

Need more worker nodes? Just update the count of your worker resources and let the system take care of it.

IaC lets you rest easy knowing that what you’ll get is precisely what you said you wanted. No mis-clicks, no confusing UI changes, just plain text code in a file.

Well-Defined Outputs

If you’ve ever used the AWS console wizards, you know that it often creates extra resources for you in the background while also creating the thing you originally wanted.

This can be helpful, but it can also make it impossible to know precisely what was created, by whom, and for what purpose.

With IaC, you’re getting exactly what you’ve specified, and nothing else.

That does mean you have to know what you need in the first place, and specify it in your IaC module, but it also means you can be confident that you don’t have any hidden dependencies anywhere that will result in surprise charges.

Modularity/Reusability

One of the core principles of software development is modularity.

Take something that you need to do multiple times and abstract it away into a reusable function/class/script.

IaC lets you do the same thing, but for your infrastructure. Instead of having to click through the web console, following a guide on the wiki that you hope is the up-to-date way of doing things (or worse, wishing desperately that you had written a guide the last time you did this), you can just use your handy-dandy module.

Just give it your unique input parameters and awaaay~ you go!

Self-Documenting Architecture

Architecture diagrams are excellent. I highly recommend them.

I also know that none of us spend as much time documenting our systems as we should. There’s always something more important to do.

We get around this with our codebases by using automated tools that do the basic documentation for us.

But if you’re building infrastructure by hand, you’re stuck back in the Stone Age. How many servers were created? How many databases? Which ones have acccess to what others?

Realistically, we just throw up our hands and ignore it, pledging to Eventually™ get around to documenting it all in a nice, pretty diagram.

Never gonna happen.

If you define your infrastructure with code, then you at least have a clear place that documents exactly what you were building. Heck, the good systems will let you put in comments to explain what your intentions were and why you made the decisions you did.

Asynchronous Actions

One subtle benefit that only becomes clear after a while of using IaC is that it allows you to time-shift your work and effort.

Despite all our best efforts, some changes have to take down the production systems. Inevitably, you’ll end up scheduling these updates for after-hours. Then you’ll sit there, possibly for multiple hours, applying updates step by step, waiting for each step to complete before moving on to the next one.

Been there, done that, it sucks. I was willing to do that when I was fresh out of college, but not anymore.

If you write your changes as code, though, then you can do all the hard work up-front during your normal working hours, and just take 10 minutes to run it after-hours.

If you’re confident in your IaC, you can even just schedule the updates to be pushed out automatically and check on it in the morning.

A closely-related benefit is that the person writing the code doesn’t have to be the one to execute it.

So if you’re working in a team, you can have a junior member that would never be allowed access to prod infrastructure that is actually writing the infrastructure updates. Then their IaC gets reviewed by a more senior teammate, and once approved it can be run by anyone with sufficient privileges (including an automated system).

When you separate your infrastructure definition from the actual process of creating those resources, a whole realm of better workflows starts unfolding.

Tools

There are way too many IaC tools out there to list here. I’ll give you my top two suggestions, and leave the rest for you to evaluate as you get more experience.

Terraform

Terraform is one of the most popular IaC tools currently in use.

It’s open-source, it’s cloud-agnostic, and it’s got a massive set of providers available for creating resources. Chances are if you have a service you want to build infrastructure on, there’s already a provider for it.

I recommend Terraform over cloud-specific tools like CloudFormation simply because of that flexibility. Multi-cloud isn’t as common as people make it out to be, but there are plenty of other services like DNS and source control repositories that can benefit from being provisioned using the same tool.

Ansible

Ansible is a tool for configuring your resources after they’re provisioned. If you would use Terraform to spin up an Ubuntu LTS virtual machine, Ansible is what you’d use to automate the installation of services, config files, and everything else you need the VM to have.

You’ll often find it referred to as a configuration management tool, but it absolutely qualifies as defining your infrastructure as code.

Action Steps

Ready to get going and Automate All the Things?

  • Use Ansible to configure some small piece of your servers. Slowly increase how much of your configuration you end up doing with Ansible. Eventually you’ll have automated the entire process.
  • Use Terraform to spin up your next cloud VM. AWS, GCP, and Azure all have well-maintained and usable providers.
  • Read The Comprehensive Guide to Terraform by Gruntwork for an in-depth, play-by-play walkthrough of the process of using Terraform.

Next up: CI/CD and how to simplify your daily workflow.