I'm fairly new to TF and wonder how people are structuring Terraform for bigger infrastructure. We are moving our infrastructure to Terraform bit by bit. I'm curious how people are approaching that.

Let's assume we have:

  • Cloudfront for our API
  • API implementation using bunch of AWS Lambdas
  • legacy service EC2 hosted backed by MySQL
  • lambdas are using legacy service and DynamoDB to fulfill requests

How would you go about and structure Terraform for project like that? Would you put all into one Terraform or split them? If so what's your approach to split TF code? by context?

We also want to move our punch of API lambdas to CI/CD. They are split into multiple code repos and we would like to Terraform them as well. How to link TF for each Lambda with the TF for the rest of infrastructure?

  • You should probably break off the lambda part at the end into its own question.
    – Levi
    Commented Jul 18, 2022 at 18:18

2 Answers 2


Sorry for adding a direct answer, I cannot add comments still.

So from what I have worked with and especially in companies that already had legacy infrastructure with legacy Terraform, that was not well written, what I would first suggest:

  1. Read the book Terraform: Up & Running, 2nd Edition Link, it helped me a lot!
  • It will give you an idea of how to structure your Terraform and other amazing things. There is also a git repo for this book:GitHub
  1. Create modules, as much as you can.
  • You can create a module for Cloudfront for example, that can later be reused in other environments.
  1. Don't use one state file. Split when needed the state file, for example, if you have EC2 instances that use a ec2.tfstate and you have an EKS cluster, don't use them in the same state, create an eks.tfstate file that will be only for the EKS. Another thing is, don't use local tfstate files. If you are in AWS for example create an S3 that is split by live/ /staging/ legacy/ or whatever fits the needs structure and in there put your ec2,eks,cloudwatch or other state files.
  2. You can split your terraform in multiple repos if needed, but being in one repo, split into folders and environments works in big infrastructure as well. But you have to have some kind of rules, patterns and structure on how to write terraform, so it follows one way across all your engineers.
  • Example decide on naming conventions.
  • Decide that xx amount of terraform will be built in modules, rather than just random .tf files.
  • Decide how you will execute it.
  • Manual execution: This approach is not really a good idea as that means an engineer somewhere is doing a terraform apply from his laptop. But its still something you can do if needed.
  • Pipeline: If possible as you asked building some kind of CI/CD pipeline that does a terraform init,plan, before terraform apply --auto-approve, so you know what the changes are before being approved, that will help you go back and see on a specific deployment what the terraform plan outputted and have some monitoring over it(also that will allow a few reviews and approvals from other engineers). Also, that means things can be scheduled as well. Terraform works great with Azure DevOps, GitLab and GitHub actions, from what I have worked with.
  1. To talk about legacy infrastructure. You have to decide is it worth managing a specific infrastructure that was created manually, with Terraform. What I mean is that if after a few months you will migrate that legacy infra and working on importing the legacy infra to terraform will take you a lot of time, by all means, it's not worth it. Before writing terraform, you need to sit down and plan everything: The good, the bad and the not worth it in the long run.
  2. Make code reviews for Terraform, the same way you would for code.

Going back to point number 1, read the book. Its 600 pages with 70% of it are examples. Go through the repo that I shared and see some example structure, even though that's small, believe me if you split it by env and modules, for example, those 4 points you gave at the top: Cloudfront, API, EC2, Lambdas, if you put them in separate modules folders all under modules, that would be much clearer. It's a small start, but it has to start from somewhere. You cannot import 5 years of infra at once. Take it piece by piece. Also, that's how I would deploy it as well. Deploy a VPC, then deploy on top an EC2, and so on, if you get my point.


I usually break companies' terraform into several repositories.

  1. terraform-accounts - This is used to create and harden AWS accounts using aws orgs.
  2. terraform-networking - This is used to provision company networking. Not only the VPC's but connections to/from AWS.
  3. terraform-infra - General shared infrastructure like buckets for big data or SCM or w/e. This stuff is usually owned by the platforms/infa/IT team.

Once the above is taken care of then the rest depends on how the people are organized for that company. So if it's based on applications then I create a repository for every application, but usually, it's based on teams. So I create a repository for every team.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.