You should follow Terraform official style guide。It talks about module structure, multiple environment and their branching strategy
https://developer.hashicorp.com/terraform/language/style
Multiple environments
that your repository's main branch be the source of truth for all environments. For Terraform Cloud and Terraform Enterprise users, we recommend that you use separate workspaces for each environment. For larger codebases, we recommend that you split your resources across multiple workspaces to prevent large state files and limit unintended consequences from changes. For example, you could structure your code as follows:
.
├── compute
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
├── database
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── networking
├── main.tf
├── outputs.tf
└── variables.tf
In this scenario, you would create three workspaces per environment. For example, your production environment would have a prod-compute, prod-database, and prod-networking workspace.
Refs: https://developer.hashicorp.com/terraform/language/style#multiple-environments
Repository structure
Organize your infrastructure configuration in repositories that group together logically-related resources. For example, a single repository for a web application that requires compute, networking, and database resources . By separating your resources into groups, you limit the number of resources that may be impacted by failures for any operation.
Another approach is to group all modules and infrastructure configuration into a single monolithic repository, or monorepo. For example, a monorepo may define a collection of local modules for each component of the infrastructure stack, and deploy them in the root module.
.
├── modules
│ ├── function
│ │ ├── main.tf # contains aws_iam_role, aws_lambda_function
│ │ ├── outputs.tf
│ │ └── variables.tf
│ ├── queue
│ │ ├── main.tf # contains aws_sqs_queue
│ │ ├── outputs.tf
│ │ └── variables.tf
│ └── vpc
│ ├── main.tf # contains aws_vpc, aws_subnet
│ ├── outputs.tf
│ └── variables.tf
├── main.tf
├── outputs.tf
└── variables.tf
Refs: https://developer.hashicorp.com/terraform/language/style#repository-structure
Module repository names
The Terraform registry requires that repositories match a naming convention for all modules that you publish to the registry. Module repositories must use this three-part name terraform--, where reflects the type of infrastructure the module manages and is the main provider the module uses. The segment can contain additional hyphens, for example, terraform-google-vault or terraform-aws-ec2-instance.
Refs: https://developer.hashicorp.com/terraform/language/style#module-repository-names
Other Important links to consider
https://developer.hashicorp.com/terraform/language/style#branching-strategy
Terraform configurations * environments = workspaces
: terraform.io/docs/enterprise/guides/recommended-practices/… – Stretch