Organizing Terraform config with app code


I’m sort of the main infrastructure/DevOps person in my organization, and recently, I started using Terraform to codify our infrastructure. I also launched a new product from within the organization whose infrastructure is completely managed by Terraform.

Currently, I have the Terraform config in a separate repo in the group I maintain for DevOps activities (dockerfiles, Chef cookbooks, Helm charts, and now Terraform config), but I’m wondering if this is really good practice…
On the one hand, Terrraform deserves a separate repo, because it’s a separate, cross-cutting domain, affecting both backend and frontend (potentially. Depending on the config.), so it shouldn’t be mixed in with program code.
On the other hand, placing Terraform configs in the same repo allows better and more concise overview/auditing, since everything is available in one place to define the state of the system, without having to clone multiple repos.

So my question is: what’s the current best practice, should I place Terraform config in with my app code, or keep it in a separate repository?
The same question goes for managing multiple apps, should config be placed in the app repositories and versioned there (with versioning mixed in with app code versioning), or in a separate repository (where versioning is mixed in with all other infrastructure, not just the app being audited)?

It depends on your project. For me, when I had 10+ microservice repositories, I had a Terraform subdirectory per microservice repo with all the Terraform specific to that microservice. Also, the Dockerfiles would be in their respective microservice repos. In addition, I would have a Terraform repo containing all the generic Terraform stuff that wasn’t specific to a single microservice (load balancers, Kubernetes cluster, security rules, etc.).

However, currently I am working on a monolithic project (all application logic in a monorepo), and I keep all my Terraform in a separate infra-as-code repo. It’s clear to me this way: changes in app logic should be in the app repo, changes in infra logic should be in the infra repo. Also, I want to set certain git policies that I don’t need to set for my application logic.

There are a few advantages when keeping your Terraform config in a separate repo.

  1. Separation of concerns
    The infra setup of your application is a clear, separate responsibility within all responsibilities regarding your application. Especially the generic infra part.
  2. Managing access
    Maybe want to restrict which team members can make changes to your infra. Or you want only a pipeline to be able to clone and execute your Terraform. You can’t set restrictions like this if the Terraform is in the same repo as your application logic.

If you’re worried about cloning multiple repos, there are many tools like meta-git to make your life easier.

Hope this helps :slight_smile:

That’s pretty much what I was thinking too, and it confirms my suspicions that, like with many other problems, there is no silver bullet or single best practice.

Since this latest product is (more or less) microservice-based, with separate backend and UI modules, I believe I’ll go with the in-repo Terraform files.

Thanks for confirming my suspicions!

Have a great holiday!

1 Like