IaC Patterns – keep things clean
You’ve heard of Infrastructure as Code (IaC) but have you heard of IaC Patterns? A lot of people are jumping on Terraform and Cloudformation to deploy their applications and infrastructure. If you’re reading this than I’m pretty sure you’re one of those people. But, how do you know when you’re doing things right?
I’m going to give a brief intro on what I mean by IaC patterns and then give some high level details on patterns that work. Everyone should be able to take something away from this, but these patterns will mainly apply to organizations running SaaS apps and micro-services. They are also probably Terraform specific.
What are IaC Patterns?
If you come from a developer background you’ve probably heard of the gang of four and application design patterns. You’ll find IaC Patterns are similar in that they are best practices of design elements found in infrastructure code. Basically, these are ways your organization will come up with to keep your IaC code clean, concise, and understandable to others.
Give me the details on IaC Patterns!
If you’re not already familiar with Terraform and tf concepts like locals, workspaces, modules, remote state than you will need to first read up on all of that. Good patterns rely on these concepts, so I really hope you’re more than just familiar with them. You should also know some of the dirty terraform hacks that are out there. Let me give you a quick rundown on these concepts and why you should be familiar with them, then I’ll go over those high-level details.
What can I say about locals, they’re a good way to hack around some HCL limitations. In Terraform sometimes it can be hard to handle a null value or sometimes you want to add count to a resource to either turn it off or on, not necessarily to increase or lower the count. This is when you can turn to locals to fix those limitations. (I’ll add examples here eventually… maybe…)
Workspaces allow you to deploy different environments easily. Staging/Development/Production should all be separate workspaces. Different regions should be separate workspaces. You can use
terraform.workspace in your code to figure out which workspace you’re in. You want to test something out? Make a branch and deploy off of a workspace named after your branch. Just make sure not to forget to add a .tfvars and update your code where you rely on terraform.workspace
I feel like this is self explanatory. Modules make your code more modular. When deploying a new app, if your aren’t using modules to deploy your app you’re not doing too great, but it’s not necessarily terrible. But if you’re not using modules to deploy your infrastructure you are a few steps behind. You should rarely rely on general Terraform resources. Make your code modular. Good examples on modules would be to make modules for resources or groups of dependent resources. I’ve also seen some places that make one giant module for their whole infrastructure. I feel like the former is cleaner but the latter makes new deployments faster and easier if the giant module is kept up.
Remote state is really important. Use S3 buckets with version history turned on! Remote state is what allows you to decouple your application from your infrastructure.
Now for those details…
This diagram includes a general overview on how to layout your code as well as some tips on things to do. Create separate repos for your App, App-IaC, and any global dependencies (VPC for sure). The App should only rely on outputs from the IaC remote state to build out the remaining resources for the app (generally ecs tasks/defintions or ec2 instances) and to set env vars the app needs to function (DB urls, DB credentials, other resource details, etc). This is in no way all encompassing but I’ve made it to give some tips I’ve learned the past couple years that didn’t seem to stick out until I’ve already seen them. Below are a few close-ups of the tips.
Now find your IaC Patterns
Now that you’ve been given some hints and pokes in the right direction, go find what patterns work for you and your org. I’m sure even if you’re running more static resources you can take something away from this that will work for you. Post a comment if you have anything good to share on this topic, I’d love to see other things I’m missing.