How to manage separate terraform templates that are part of the same big project?

Hello Everyone!

I have a question for you. What is the best practice to manage infrastructure with terraform for applications that are managed separately but that are related. In other words and more specifically. . .in my current project we have been managing the infrastructure using terraform templates but, project’s scope is expanding and now we have other satellite applications with their own repos and infrastructure (with their own terraform templates) but at some point the infrastructure of both apps overlaps (Resource created in one terraform template, lets say an sqs queue, needs to be referenced in another terraform template to create a sns/sqs subscription)

How should we manage their infrastructure with terraform? In a single terraform common repository (using modules and 1 single state file)? or in separate repos (like a terraservice pattern , each terraform project with its own state file)? using terraform data sources ? De-compose the “shared” infrastructure in another module or repo?

Thanks in advance team!

That’s a pretty broad question!

As with many questions there is no “right” answer, and can depend on may factors including team(s) make up, frequency of change and desired binding levels.

For us we generally have a repo (and associated state file) for a single deployable unit (and achieve this via CI/CD). For small applications that might be a single repo, but as things get larger we generally split things based on the responsible team (try to keep ownership simple, so avoid repos with shared ownership), change cadence (often will keep things which change very often separate from things that hardly change - for example underlying platform/infrastructure compared with applications), dependencies (sometimes it is much simpler to split things instead of trying to figure out a way to make Terraform do the right thing - for example split Kubernetes cluster infrastructure and namespace setup code) and relationships (we’d keep similar things together but keep different things apart - different repos for totally different unrelated products for example).

With regards to linking between repos (for example an application repo needing information about underlying infrastructure or applications needing knowledge of each other) which mechanism we use depends on the level of dependence we want. For strong dependence (for example parts of the same product) we’d often use remote state with outputs & the remote state data source. For this you have to be careful to orchestrate changes correctly - you can’t run a dependant repo until the dependency has completed for example. For loose dependencies we might just store the name of a resource (and then use data sources if more details are needed). We might do this with URLs, queue names and S3 buckets for loosely coupled applications. You have to be careful keeping things in sync as there is no automatic flow of updates - you could use some automation to create PRs for you if desired.

Thank you Stuart !

Definitely this is a very broad question and I was expecting a “there is not a silver bullet” answer hehe.

We have been discussing this internally and there are also several opinions about how to approach such scenarios.

We will try with an approach that will separate the resources that creates high dependencies into its own repo as we are looking to minimize the occurence of circular dependencies between the terraform projects.

Send good vibes :stuck_out_tongue: