gruntwork-io / terragrunt

Terragrunt is a flexible orchestration tool that allows Infrastructure as Code written in OpenTofu/Terraform to scale.
https://terragrunt.gruntwork.io/
MIT License
7.91k stars 966 forks source link

Dynamically create dependency blocks #2593

Open gtmtech opened 1 year ago

gtmtech commented 1 year ago

Describe the solution you'd like

I am fetching my dependencies from external commands for reasons.

This works with dependencies block as I can inject into the paths attribute:

locals {
  dependencies = jsondecode(run_cmd("./get-dependencies.sh")) # returns e.g. '[ "module3", "module7" ]'
}

dependencies {
  paths = [ for d in local.dependencies: format("../%s", d) ]    
}

But I cannot do this for dependency block, because dependency is a block. I note from https://github.com/gruntwork-io/terragrunt/issues/1571 that it is said that it is not currently supported to generate dependency dynamically.

I would like this ability natively supported

Describe alternatives you've considered

Searching for ways to achieve this. I thought of a hacky way to do it as follows:

dependency "module1" {
  config_path = "../module1"
  mock_outputs = jsondecode(run_cmd("./get-dependency-mock-outputs.sh module1"))
}
include "dep1" {
  path = contains(local.dependencies, "module1") ? find_in_parent_folders("dep-module1.hcl") : find_in_parent_folders("dep-null.hcl")
  expose = true
}

include "dep2" {
  path = contains(local.dependencies, "module2") ? find_in_parent_folders("dep-module2.hcl") : find_in_parent_folders("dep-null.hcl")
  expose = true
}

... etc...

Would work, but not exactly friendly or DRY

Additional context

joaocc commented 1 year ago

Hi. Would also love to have this, as otherwise it's not possible to have truly dynamic infrastructures, as dependencies end up being static, without resorting to some techniques like aggregating elements in a source module with multiple elements so it's only 1 dependency. Maybe this is difficult due to the impact on graph generation, but would be very useful nevertheless.

kristijorgji commented 11 months ago

Hi I would also love to have this.

My use case is this: I am testing different architectures and want to export ssm vars based on the fact that some env variable is set.

If USE_ALB is set want to create and export load balancer vars, otherwise do something else.

terraform {
  source = "github.com/kristijorgji/terraform-aws-ssm-store?ref=v1.1.0"
}

// TODO include dynamically only if tobool(get_env("TG_USE_ALB", "false")) === true
dependency "alb" {
  config_path = "../alb/instance"
}

inputs = {
  kms_alias = "alias/aws/ssm"

  name_prefix = "/test"

  overwrite = true
  parameters = concat(
    [
      {
        name      = "dafsasdffds"
        value     = "dada"
        type      = "SecureString"
        overwrite = true
      },
    ],
    tobool(get_env("TG_USE_ALB", "false")) ? [
      {
        name  = "lb_https_listener_arn"
        value = element(dependency.alb.outputs.https_listener_arns, 0)
    }, ] : []
  )
}