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
8.04k stars 975 forks source link

The object does not have an attribute named {{ value }} with mock_outputs defined. #2671

Closed mgopez closed 1 day ago

mgopez commented 1 year ago

Describe the bug Given the following Terragrunt structure:

.
├── module_1
│   └── terragrunt.hcl
└── module_2
    └── terragrunt.hcl

Where module_2 has an explicit dependency on module_1.

dependency "module_1" {
  config_path = find_in_parent_folders("module_1")
  mock_outputs = {
    some_derived_value = a_mock_value
  }
}

inputs = { 
    a_variable = dependency.module_1.outputs.some_derived_value
)

If module_1 fails its deploy, but has a resource in it like an azurecaf naming resource. That azurecaf naming resource is created, and the state file of module_1 is populated with the following:

{
  "resources": [
    {
      "mode": "managed",
      "type": "azurecaf_name",
      "name": "subnet",
      "provider": "provider[\"registry.terraform.io/aztfmod/azurecaf\"]",
      "instances": [
        {
          "schema_version": 3,
          "attributes": {
            "clean_input": true,
            "id": "an_id",
            "name": "name-of-resource-init",
            "passthrough": false,
            "prefixes": null,
            "random_length": 0,
            "random_seed": null,
            "resource_type": "module_1_s_resource_type",
            "resource_types": null,
            "result": "the-name-of-the-resource",
            "results": {},
            "separator": "-",
            "suffixes": [
              "suffix-1",
              "suffix-2"
            ],
            "use_slug": true
          },
          "sensitive_attributes": [],
          "private": "REDACTED"
        }
      ]
    }
  ],
  "check_results": null
}

The state file exists with elements in the resource list but the actual Terraform resource that module_1 contains is not deployed due to some error and is not present in the resource list.

Now for every subsequent run of the project, during the init phase we can observe the following:

Unsupported attribute; This object does not have an attribute named "some_derived_value"., and 1 other diagnostic(s)

It appears that during the init phase that due to the existence of the state file and the resources list is populated, Terragrunt attempts to resolve some_derived_value from the state file rather than using the mock defined in the mock_outputs block.

To Reproduce Steps to reproduce the behavior, code snippets and examples which can be used to reproduce the issue.

  1. Assuming the module structure above.
  2. Make a configuration error that results in module_1 failing to deploy the Terraform resource.
  3. Run terragrunt run-all init.
  4. Observe that module_1 failed to deploy, but its azurecaf naming resource was created.
  5. Fix configuration error for module_1.
  6. Run terragrunt run-all init.

You should see the error now.

Expected behavior Terragrunt checks the resources list and verifies if the Terraform resource is deployed by checking the type of the element.

Versions

mgopez commented 1 year ago

A workaround for this issue is to delete the state file of module_1 and re-run terragrunt run-all init

github-actions[bot] commented 1 week ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for raising this issue.