I think all your points are valid, but I've also had good results using workspaces for environments. Here's generally how I structure my terraform primarily targeting AWS.
- 1 Terraform workspace per environment (dev, test, prod, etc.).
- Managing changes to workspaces / environments is done with whatever approach you use for everything else (releasing master using some kind of CICD pipeline or release branches). The Terraform is preferably in the same git repositories as your code but can be separate.
- The CICD tool injects an environment variable into the build to select the appropriate workspace and somehow supplies credentials granting access to a role that can be assumed in the appropriate account.
- A region module / folder that defines the resources you want in each region. This is your "main" module that specifies everything you want.
- Minimal top level terraform that instantiates multiple AWS providers (one for each region) and uses them to create region modules. Any cross region or global resources are also defined here.
- The region module uses submodules to create the actual resources (RDS, VPCs, etc.) as needed.
This approach assumes you want to deploy to all your regions in one go. That may not be the case.
- 1 Terraform workspace per environment (dev, test, prod, etc.).
- Managing changes to workspaces / environments is done with whatever approach you use for everything else (releasing master using some kind of CICD pipeline or release branches). The Terraform is preferably in the same git repositories as your code but can be separate.
- The CICD tool injects an environment variable into the build to select the appropriate workspace and somehow supplies credentials granting access to a role that can be assumed in the appropriate account.
- A region module / folder that defines the resources you want in each region. This is your "main" module that specifies everything you want.
- Minimal top level terraform that instantiates multiple AWS providers (one for each region) and uses them to create region modules. Any cross region or global resources are also defined here.
- The region module uses submodules to create the actual resources (RDS, VPCs, etc.) as needed.
This approach assumes you want to deploy to all your regions in one go. That may not be the case.