Separate files for vars, outputs, data, files, resources, locals, etc

Greetings, this is a best practice question. I’ve been arguing about the layout of TF files with some of my colleagues, especially in more complex modules (root module included).

I feel like separating things by their language feature/resource type is not a modern approach, however the info I’ve been able to find out there seems to be for beginner tutorials/simple infrastructure. We’ve evolved way past that and just want to make sure we’re not just following some beginners guide and it is actually a best practice.

current practice:

Have everything split out to inputs.tf, outputs.tf, data.tf, s3.tf, sns.tf, etc. Some files only have a single resource or module in there.

Alternative:

Splitting things up with resources related to a particular function together in a single file. For example an S3 bucket that sends a notification to and SES endpoint (pagerduty)

The single file would contain:

  • the bucket
  • the SNS topic and subscription
  • the variable for the pagerduty endpoint
  • data resource iam policy doc
  • if there is a resource that is used outside of this file, than it could be put in a global resources/vars/data/outputs file, etc.

Note: that this could be a module(internal/external), however we’re trying to flatten things out and we won’t need to re-use this.

I come at this from developing in many different languages, and the current way we split things up seems to be a bit archaic … akin to how we had to define variables at the top of a function at one time(K&R C), or scoping everything as global in Python. Back in the day
compilers/interpreters just couldn’t handle scoping a variable inside a loop or if block, but times have changed. Yet I feel like I took a step back in time when I read Terraform code, but I suspect its just that most tutorials/howto are written with the beginner in mind and not advanced Terraform best practice.

I’d appreciate any thoughts/references.

Best

1 Like