Dependency mock_outputs and terragrunt plan

I’m currently playing around with terragrunt, after it being mentioned at work, and am currently kicking the tires to understand how it would work given certain scenarios.

The scenario I’m currently looking at is when two modules get updated with one module including a dependency on a new output from the other module and in this scenario, assuming some sort of PR has been raised, you’d want to run plan-all to allow the reviewer to understand what changes they are approving.

Looking at the README, it seems that this would be where mock_outputs would be used but I get the following error when attempting to plan: [terragrunt] 2019/10/09 14:16:27 .../two/terragrunt.hcl:18,33-41: Unsupported attribute; This object does not have an attribute named "output2".

Is this something that is expected to work? Does it only work with ‘real’ backends other than local? Does Terragrunt currently not support this?

Module one:

terragrunt.hcl

terraform {
  source = "/test/terragrunt/one-source"
}

with the Terraform within that module looking like this, with an output2 being added as the update

resource "random_string" "foo" {
  length = 12
}
output "output" {
  value = random_string.foo.result
}

Module two

terragrunt.hcl, with mock_outputs = {output2 = "foobar"} being added to the dependency and dependency.one.outputs.output being changed to dependency.one.outputs.output2 in the updated

terraform {
  source = "/test/terragrunt/two-source"
}

dependency "one" {
  config_path = "../one"
}

inputs = {
  input = dependency.one.outputs.output
}

with the Terraform within the second module looking like

variable "input" {}
resource "local_file" "foo" {
  content  = var.input
  filename = "${path.module}/foo.txt"
}

TF_LOG=debug terragrunt plan

[terragrunt] 2019/10/09 14:51:09 Reading Terragrunt config file at /test/terragrunt/eu-west-1/two/terragrunt.hcl
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 Reading Terragrunt config file at /test/terragrunt/eu-west-1/one/terragrunt.hcl
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 Running command: terraform --version
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 WARNING: no double-slash (//) found in source URL /test/terragrunt/one-source. Relative paths in downloaded Terraform code may not work.
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 Detected 1 Hooks
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 Downloading Terraform configurations from file:///test/terragrunt/one-source into /test/terragrunt/eu-west-1/one/.terragrunt-cache/0gjbg--TRRhIIvLOAWskgoGZmQg/Jv0zd3GQf2yBg1Tkt6DclnH5fIQ
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 Copying files from /test/terragrunt/eu-west-1/one into /test/terragrunt/eu-west-1/one/.terragrunt-cache/0gjbg--TRRhIIvLOAWskgoGZmQg/Jv0zd3GQf2yBg1Tkt6DclnH5fIQ
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 Setting working directory to /test/terragrunt/eu-west-1/one/.terragrunt-cache/0gjbg--TRRhIIvLOAWskgoGZmQg/Jv0zd3GQf2yBg1Tkt6DclnH5fIQ
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 Detected 1 Hooks
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 Executing hook: get_config
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 Running command: /test/terragrunt/.scripts/config.sh eu-west-1/one /test/terragrunt/eu-west-1/one
[terragrunt] [/test/terragrunt/eu-west-1/one] 2019/10/09 14:51:09 Running command: terraform output -json
2019/10/09 14:51:09 [INFO] Terraform version: 0.12.10
2019/10/09 14:51:09 [INFO] Go runtime version: go1.13.1
2019/10/09 14:51:09 [INFO] CLI args: []string{"/usr/local/bin/terraform", "output", "-json"}
2019/10/09 14:51:09 [DEBUG] Attempting to open CLI config file: /Users/wjam/.terraformrc
2019/10/09 14:51:09 [DEBUG] File doesn't exist, but doesn't need to. Ignoring.
2019/10/09 14:51:09 [INFO] CLI command args: []string{"output", "-json"}
2019/10/09 14:51:09 [DEBUG] checking for provider in "."
2019/10/09 14:51:09 [DEBUG] checking for provider in "/usr/local/bin"
2019/10/09 14:51:09 [DEBUG] checking for provider in ".terraform/plugins/darwin_amd64"
2019/10/09 14:51:09 [DEBUG] found provider "terraform-provider-random_v2.2.1_x4"
2019/10/09 14:51:09 [DEBUG] found valid plugin: "random", "2.2.1", "/test/terragrunt/eu-west-1/one/.terragrunt-cache/0gjbg--TRRhIIvLOAWskgoGZmQg/Jv0zd3GQf2yBg1Tkt6DclnH5fIQ/.terraform/plugins/darwin_amd64/terraform-provider-random_v2.2.1_x4"
2019/10/09 14:51:09 [DEBUG] checking for provisioner in "."
2019/10/09 14:51:09 [DEBUG] checking for provisioner in "/usr/local/bin"
2019/10/09 14:51:09 [DEBUG] checking for provisioner in ".terraform/plugins/darwin_amd64"
[terragrunt] 2019/10/09 14:51:09 /test/terragrunt/eu-west-1/two/terragrunt.hcl:16,33-41: Unsupported attribute; This object does not have an attribute named "output2".
[terragrunt] 2019/10/09 14:51:09 Unable to determine underlying exit code, so Terragrunt will exit with error code 1

Hi Will,

Welcome to the community!

mock_outputs is only used if one of the following two conditions is true:

  • The upstream dependency has no outputs in the state file. This is the case if the module has never been applied.
  • skip_outputs is set to true on the dependency block.

For all other cases, the regular outputs of the upstream module is used. In this case, if you have already applied the upstream module, terragrunt will default to using those outputs and therefore, it won’t see the output2 in the mock_outputs.

As far as trying to get the plan to work correctly in a cross module scenario: this is unfortunately not a supported use case yet. Terragrunt (by design) doesn’t do any kind of processing on the plan output, so it has no way of passing forward plan changes to downstream dependencies.

We also unfortunately don’t really have a good workaround at the moment for this particular scenario. The best thing you could do right now is to be diligent about the changes in the review and predict possible outcomes downstream based on the plan output of the upstream dependencies.

Best regards,
Yori