terramate icon indicating copy to clipboard operation
terramate copied to clipboard

[FEATURE] `globals/imports` specific to given stack, without impact on child stacks?

Open arathunku opened this issue 1 year ago • 3 comments

Is your feature request related to a problem? Please describe.

Is there a way to define "globals" only for specific stack and remove it from consideration for any child stacks?

Example structure:

deployments/
  providers.tm.hcl # generates code for providers for stacks
  todo-app/
    stack.tm.hcl
    eu-west-1/
       stack.tm.hcl

In deployments/todo-app/stack.tm.hcl we define some globals, for example to turn on aws, cloudflare and some other provider but todo-app's substack only need aws provider.

Now, due to how globals are merged, any changes to globals on todo-app/stack.tm.hcl are automatically impacting globals on todo-app/eu-west-1/stack.tm.hcl which is fine in most of the cases.

Describe the solution you'd like I'd like to be able to scope specific changes to "globals" to stack.


globals "use_providers" {
  aws  = true # changes globals for this and any child stacks
}

stack {
  globals "use_providers" {
    cloudflare  = true # changes this value only for this specific stack, no impact on child stack
  }
  import { ... }

  name = "todo-app"
}

Describe alternatives you've considered

At this moment, there's a workaround, a child stack MUST overwrite anything it doesn't need/want from parent stack but it gets very ugly.

Alternative, don't have any child stacks.


EDIT:

:scream: it looks like the same goes for imports?

arathunku avatar Nov 22 '23 12:11 arathunku

As a workaround you can use tags instead of globals and conditionally enable it based on the existence of a tag.

e.g. tags = ["tf-provider-aws"] and then use condition = tm_contains(terramate.stack.tags, "tf-provider-aws") in the generate_hcl block.

This comes with the additional benefit of being able to list all stacks having a given provider with terramate list --tags tf-provider-aws.

We are currently discussing stack-level lets {} support that we can add in a future release so you could reference terramate.stack.let.use_providers and not inherit the values to child stacks anymore. Would such a feature be valuable for you?

mariux avatar Nov 23 '23 11:11 mariux

I'd say the workaround focuses a bit too much on providers. Provider is one of few configuration options, there are others that may impact (un)expectedly child stacks. For now, at this moment, to get unblocked we've removed any nesting within stacks, moved stacks into another directory next to child stacks and added a guideline with a ref to this issue to avoid introducing any stack nesting.

We are currently discussing stack-level lets {} support that we can add in a future release so you could reference terramate.stack.let.use_providers and not inherit the values to child stacks anymore. Would such a feature be valuable for you?

:thinking: I'm not sure if I like it :see_no_evil: It adds another way of setting and getting variable values, and it doesn't address in any way inherited import { }. My original suggestion still stands, support for blocks such as globals and import, but within stack { } block. When child stacks are evaluated, they would be skipped.

Real example from one of our apps

  • parent stack defines DNS record via imported module for provider agnostic DNS definitions
  • child stacks are specific deployments for given app in regions, with region specific features, they're not aware of "DNS" configuration

Because the parent stack imported DNS module via terramate, all child stacks now try to use a provider they don't need and terramate generates code for DNS within child stacks.

arathunku avatar Nov 23 '23 12:11 arathunku

We are planning to support stack level lets blocks that does not inherit to nested child stacks and will be available as terramate.stack.let namespace. In addition we want to support an generate_hcl.inherit and generate_file.inherit flag that will prevent generate blocks from being inherited when set to false. This will also support imported generate blocks. Sadly, there is no ETA we can share atm.

mariux avatar Jan 25 '24 22:01 mariux