I've been using Hiera (Puppet yaml data store) to source data for terraform. As a long time puppet user, when I started writing terraform code I really missed hiera. Turns out someone ported it to Go, and someone else turned that into a terraform provider. It's a game changer. No need for terragrunt or terramate. Hiera can return anything from a single value to a very complex data block that can be used to feed a module or a whole stack. Hiera needs some information about where you're deploying to, and it gets this in the in the provider configuration in the form of key/vals: I use environment, region & stack. I decided to use a workspace naming convention that encodes these (eg: prod_use1.network). For each workspace, terraform can automatically figure out exactly what lookups it needs to do, and hiera returns native terraform data relevant to that workspace only. I have 100% dry code, and no need to create a separate directory for each environment/region state. I run my terraform init/apply in the top-level directory no matter where I'm deploying. The result is that once I've written my modules and stacks, I can build out a whole data center by creating few workspaces and running "terraform init && terraform apply" in each one. Zero extra files or directories. Dry as a bone
Over the weekend I plan to cut out the heart of my setup, make it generic enough to share on GitHub and do an extremely short video walkthrough of how I use it. (Except I know how my plans don't always get turned into actions)