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

Enhance evaluation of maps members within locals #1818

Open daniel-anova opened 2 years ago

daniel-anova commented 2 years ago

When using the following code example:

locals {
  values = {
    this = "this"

    // error: "Could not evaluate all locals in block."
    name     = local.values.this
    location = "eastus"
  }
}

terraform {
  source  = "tfr://registry.terraform.io/bcochofel/resource-group/azurerm?version=1.4.1"
}

generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
provider "azurerm" {
  features {}
}
EOF
}

inputs = local.values

it produces the error "Could not evaluate all locals in block" when referencing a sub value of a map within the map itself. Moving that value outside the map works normally.

Could evaluation of maps within locals be evaluated in the same more "robust" way locals are evaluated to allow the above to work without error?

Alternatively could erros be clearer in pointing which block is failing to evaluate and why.

yorinasub17 commented 2 years ago

I'm not sure this is feasible given the parsing tools we have from the hcl library and the current approach. AFAIK, to implement this, we will need to overhaul the parsing mechanism to use a lazy evaluation approach like terraform, which is a major transition (not to mention more difficult to maintain).

I think we will consider a community PR to implement this, but will most likely not implement it ourselves.

Alternatively could erros be clearer in pointing which block is failing to evaluate and why.

Good point. Opened PR to enhance error message: https://github.com/gruntwork-io/terragrunt/pull/1819

Now the following will be logged for the following config:

config

locals {
  hello = var.foo
  values = {
    this        = "this"
    name     = local.values.this
    location = "eastus"
  }
}

error log

ERRO[0000] Not all locals could be evaluated:
ERRO[0000]      - hello (Can't evalute expression at terragrunt.hcl:2,11-18 because of non-local variable reference (var is not defined))
ERRO[0000]      - values (Can't evalute expression at terragrunt.hcl:3,12-9,4 because local reference 'values' is not evaluated)
ERRO[0000] Could not evaluate all locals in block.