Skip to content

Stacks: Values reference other units #4067

Open
@cgetzen

Description

@cgetzen

The problem I am currently facing with the new Stacks RFC is that it is not possible to pass the output of one unit through to the values of another in the terragrunt.stack.hcl file.

While it is possible to do this in the unit definition, this is not extensible enough because, with stacks, the units will be reused with different inputs.

Proposal

Expand the terragrunt.values.hcl file to use dependencies:

# terragrunt.stack.hcl

unit "dep" {
  source = "modules/imadep"
  path   = "imadep"
}

unit "test" {
  source = "modules/test"
  path   = "test"
  values = {
    a = "a"
    b = unit.dep.output_b
  }
}


# .terragrunt-stack/test/terragrunt.values.hcl (auto-generated)

values {
    a = "a"
    b = dependency.dep.outputs.output_b
}

dependency "dep" {
    config_path = "../imadep"
}

There is a POC of this here: #4056

POC Q&A

Recommendation to use a new terragrunt.dependencies.hcl file
I'd be happy to POC this, but I'm curious how you see the relationship between the dependencies file, values file, and terragrunt file.

My current view is that consolodating all dynamic inputs to units in the terragrunt.values.hcl is optimal:

values {
    a = "a"
    b = dependency.dep.outputs.output_b
}

dependency "dep" {
    config_path = "../imadep"
}

Yes, it is more complex than just putting (static) key-value pairs. However:

  1. the complexity has to go somewhere
  2. Putting this inside of the values file may be the least complex

Why is this the least complex?

  • I think it can clearly define interfaces and boundaries between components:terragrunt.values.hcl can be processed (i.e. dependencies resolved) and only export a single values interface. Processing would be self-contained to the terragrunt.values.hcl file, and terragrunt.hcl would only ever see the values object from it.
  • I suspect there may be other constructs that users may want to add in the future. Splitting files by block types may lead to many files with different kinds of relationships between them.

What if two dependencies are named the same thing across these different files? What's the behavior? Can the terragrunt.hcl file make reference to them?
I think the correct choice is to make the terragrunt.values.hcl file hide it's internals and only expose only an interface for retrieving the values. This helps with composability (If there is a dependency in the values file with the same name as a dependency in the terragrunt file, they will not interfere).

Are there any alternative designs that you think would work just as well?
The constraint to keep unit definitions backwards compatible (which I agree with!) reduces the solution space. I haven't been able to come up with another design.

How are mock outputs handled?
I touch on one option for this at the bottom of this comment #3313 (comment), but there are benefits to not implementing this: it trades a simple interface for flexibility. However, with additional changes it may be possible to get the flexibility of mocks with the benefits of a simple interface, and it boils down to where the mocks are defined. Instead of defining them at the "dependency" block, mock outputs could be defined at either or both of (1) the referenced units (the unit would define it's own mock outputs), and (2) in a new mock_inputs block, which is decoupled from the dependency block. I think it makes sense for a module to define mock_outputs, because the author should know what format the output takes. At the same time, I can see the value of defining mock_inputs for certain use-cases (if the dependency's output is dynamic enough where a static mock_output isn't enough).

Metadata

Metadata

Assignees

No one assigned

    Labels

    pending-decisionPending decision from maintainerspreservedPreserved issues never go stalerfcRequest For Comments

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions