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.78k stars 959 forks source link

Mock outputs doesn't work with attribute key and/or array #3201

Closed man-david closed 2 weeks ago

man-david commented 3 weeks ago

Describe the bug

I deploy different Azure resources (resource group and storage account). Storage account depend on resource groups. When I execute my code, in the Init process, all the resource groups are not already created (and I use a for_each loop inside my Terraform module), and I try to use mock outputs inside the Storage Account HCL.

Steps To Reproduce

The storage account HCL

dependency "resource-group" {
  config_path                             = "../resource-group"
  mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"]
  mock_outputs_merge_strategy_with_state  = "shallow"

  mock_outputs = {
    rg_names["scraping_concurrence_00"]     = "mock-rg"
    rg_locations["scraping_concurrence_00"] = "mock-location"
    rg_names["api_offre_prix_00"]           = "mock-rg"
    rg_locations["api_offre_prix_00"]       = "mock-location"
  }
}

inputs = {
  environment                      = local.environment_name
  scraping_concurrence_00_name     = dependency.resource-group.outputs.rg_names["scraping_concurrence_00"]
  scraping_concurrence_00_location = dependency.resource-group.outputs.rg_locations["scraping_concurrence_00"]
  api_offre_prix_00_name           = dependency.resource-group.outputs.rg_names["api_offre_prix_00"]
  api_offre_prix_00_location       = dependency.resource-group.outputs.rg_locations["api_offre_prix_00"]
}

Log error in the init process

time=2024-06-12T15:07:27Z level=error msg=Error: Ambiguous attribute key
time=2024-06-12T15:07:27Z level=error msg=  on /github/workspace/terraform/live/prd/storage-account/terragrunt.hcl line 21, in dependency "resource-group":
time=2024-06-12T15:07:27Z level=error msg=  21:     rg_names["scraping_concurrence_00"]     = "mock-rg"
time=2024-06-12T15:07:27Z level=error msg=If this expression is intended to be a reference, wrap it in parentheses. If
it's instead intended as a literal name containing periods, wrap it in quotes to
create a string literal.

I have the same error for each mock_output

Expected behavior

It should be possible to define mock value in an array where the attribute key doesn't exist yet. If not, Is there any workaround?

Versions

Thanks for your help !

denis256 commented 3 weeks ago

Hello, AFAIK, expressions like rg_names["scraping_concurrence_00"] = ... aren't valid

Valid example:

dependency "resource-group" {
  config_path                             = "../module"
  mock_outputs_allowed_terraform_commands = ["init", "validate", "plan"]
  mock_outputs_merge_strategy_with_state  = "shallow"

  mock_outputs = {
    rg_names = {
      scraping_concurrence_00 = "mock-rg"
      api_offre_prix_00       = "mock-rg"
    }
    rg_locations = {
      scraping_concurrence_00 = "mock-location"
      api_offre_prix_00       = "mock-location"
    }
  }
}

Simplified example in: https://github.com/denis256/terragrunt-tests/blob/master/complex-mock/app/terragrunt.hcl

man-david commented 3 weeks ago

Thanks for this advice.

Before the modification, I had 4 errors for each mock value because of my wrong expressions.

After changing my code, I now have only 2 errors. In fact, for the "scraping_concurrence_00" values, I already have values in the tfstate, because the resource groups are already created. And I still have errors for "api_offre_prix_00", because the resource group is not here for the moment.

This is the error log

time=2024-06-13T06:43:25Z level=error msg=Error: Invalid index
time=2024-06-13T06:43:25Z level=error msg=  36:   api_offre_prix_00_name           = dependency.resource-group.outputs.rg_names["api_offre_prix_00"]
time=2024-06-13T06:43:25Z level=error msg=The given key does not identify an element in this collection value.

time=2024-06-13T06:43:25Z level=error msg=Error: Invalid index
time=2024-06-13T06:43:25Z level=error msg=  37:   api_offre_prix_00_location       = dependency.resource-group.outputs.rg_locations["api_offre_prix_00"]
time=2024-06-13T06:43:25Z level=error msg=The given key does not identify an element in this collection value.

time=2024-06-13T06:43:25Z level=error msg=Module /github/workspace/terraform/live/prd/storage-account has finished with an error: /github/workspace/terraform/live/prd/storage-account/terragrunt.hcl:36-101: Invalid index; The given key does not identify an element in this collection value., and 1 other diagnostic(s) prefix=[/github/workspace/terraform/live/prd/storage-account] 

Do I need to change the value of "mock_outputs_merge_strategy_with_state" or something else?

Thanks

[EDIT] I change the value of mock_outputs_merge_strategy_with_state, from shallow to deep_map_only, and now it works, no more errors. But doing this, I don't use the pre-existed value from the tfstate, I think.

denis256 commented 3 weeks ago

Hi, it is not clear from the description which HCL code was used, it will be helpful to share the updated code