diegoaguilar
diegoaguilar

Reputation: 8376

What are the best DRY practices for terragrunt live with environments and regions?

I have the following folders and files structure:

├── live
│   └── environments
│       └── alpha
│           ├── control-plane
│           ├── env.hcl
│           ├── global
│           └── regional
│               ├── eu-central-1
│               │   ├── networking
│               │   │   └── terragrunt.hcl
│               │   └── region.hcl
│               └── us-west-2
│                   ├── networking
│                   │   └── terragrunt.hcl
│                   └── region.hcl
├── provider.tf
├── terraform.tfstate
└── terragrunt.hcl

Where:

locals {
  region = reverse(split("/", get_terragrunt_dir()))[0]
}
locals {
  environment = reverse(split("/", get_terragrunt_dir()))[0]
}

This is basically allowing me to replicate and isolate modules in distinct regions, which was harder with terraform some versions ago but now doable with tofu 1.8

So far I have the following concerns, goals to achive:

My needs are for multiple apps that have pretty much same design. These apps represent countries, each would have 2 distinct regions, and each need up to 5-8 regional modules.

If I have 8 countries, I have up 8 countries X 2 regions X 8 permutations which means 128 hcl files to write. I definitely care to go DRY or just make sure I get a chance on more tooling/templating.

Upvotes: -1

Views: 171

Answers (2)

Yousif
Yousif

Reputation: 34

diegoaguilar and I chatted over in the OpenTofu Community Slack about this.

This is some content that I shared with him there:

Have you had a chance to see this? https://github.com/gruntwork-io/terragrunt/issues/3313

I think that RFC is ultimately the solution you're hoping for, and would love if you gave it a reaction with a thumbs up or something. In the short term, I would investigate these two capabilities:

https://terragrunt.gruntwork.io/docs/features/catalog/ https://terragrunt.gruntwork.io/docs/features/scaffold/

Which can help with templating.

The point of a _env folder is to help with reducing repetition inside terragrunt.hcl files. If you find that you have a lot of content repeated in multiple terragrunt.hcl files, you can reduce that repetition via include configuration blocks.

You can see an example of that here:

https://github.com/yhakbar/terragrunt-3313-stacks-walkthrough/tree/main/walkthrough/03-includes-dependencies

Hopefully this helps out some other folks too!

Upvotes: 1

Troy Knapp
Troy Knapp

Reputation: 523

It sounds like you're looking for a way to generate code. I've found that Terramate is the best tool right now to be able to do this. It takes a bit of a paradigm shift, but you can code module definitions in *.tm.hcl files like:

generate_hcl "_terramate_generated_main.tf" {
  inherit = true

  condition = tm_contains(terramate.stack.tags, "networking")

  content {
    module "networking" {
      source = tm_format("[email protected]:<your org>/<your repo>.git//modules/networking?ref=%s", global.module.version.networking)         
      environment_short = global.environment_short
      <other attributes here

      providers = {
        aws        = was
        aws.infra = aws.infra
      }
    }
  }
}

Then in your stack you can have module definitions like:

globals "module" "version" {
  networking = "0.1.0",
  <other modules here>
}

Furthermore, because of the way that the globals are composed, you can have global module overrides in environments so you can slow

Upvotes: -1

Related Questions