Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reference to modules should depend on module output's, not everything in module. #35553

Open
natedogith1 opened this issue Aug 9, 2024 · 1 comment

Comments

@natedogith1
Copy link

Terraform Version

Terraform v1.9.3
on windows_386

Terraform Configuration Files

main.tf:

module "test_module" {
  for_each = toset(["a"])
  source = "./test_module"
  input = "foo"
}

resource "null_resource" "example_resource" {
  triggers = {input=tojson({for k,v in module.test_module: k => v.output})}
  lifecycle {
    create_before_destroy = true
  }
}

test_module/main.tf

variable "input" {

}

resource "terraform_data" "base" {
  triggers = {input=var.input}
}

output "output" {
  value = var.input
}

Debug Output

https://gist.github.com/natedogith1/e57533da021cf54b9fa984082127b5af

Expected Behavior

module.test_module[\"a\"].null_resource.base should be destroyed and then created

Actual Behavior

module.test_module[\"a\"].null_resource.base is created before being destroyed.

Steps to Reproduce

  1. terraform init
  2. terraform apply -auto-approve
  3. Update input="foo" in main.tf to input="bar"
  4. terraform apply -auto-approve

Additional Context

doing terraform plan -out out.plan and terraform graph -plan out.plan instead of apply in step 4, results in

digraph {
        compound = "true"
        newrank = "true"
        subgraph "root" {
                "[root] module.test_module.null_resource.base (expand)" [label = "module.test_module.null_resource.base", shape = "box"]
                "[root] module.test_module[\"a\"].null_resource.base" [label = "module.test_module.null_resource.base", shape = "box"]
                "[root] module.test_module[\"a\"].null_resource.base (destroy deposed b1459d92)" [label = "module.test_module.null_resource.base", shape = "box"]
                "[root] null_resource.example_resource" [label = "null_resource.example_resource", shape = "box"]
                "[root] null_resource.example_resource (destroy deposed c549d1ce)" [label = "null_resource.example_resource", shape = "box"]
                "[root] null_resource.example_resource (expand)" [label = "null_resource.example_resource", shape = "box"]
                "[root] provider[\"registry.terraform.io/hashicorp/null\"]" [label = "provider[\"registry.terraform.io/hashicorp/null\"]", shape = "diamond"]
                "[root] module.test_module (close)" -> "[root] module.test_module.output.output (expand)"
                "[root] module.test_module (close)" -> "[root] module.test_module[\"a\"].null_resource.base"
                "[root] module.test_module.null_resource.base (expand)" -> "[root] module.test_module.var.input (expand)"
                "[root] module.test_module.null_resource.base (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"]"
                "[root] module.test_module.output.output (expand)" -> "[root] module.test_module.var.input (expand)"
                "[root] module.test_module.var.input (expand)" -> "[root] module.test_module (expand)"
                "[root] module.test_module[\"a\"].null_resource.base (destroy deposed b1459d92)" -> "[root] null_resource.example_resource (destroy deposed c549d1ce)"
                "[root] module.test_module[\"a\"].null_resource.base" -> "[root] module.test_module.null_resource.base (expand)"
                "[root] null_resource.example_resource (destroy deposed c549d1ce)" -> "[root] null_resource.example_resource"
                "[root] null_resource.example_resource (expand)" -> "[root] module.test_module (close)"
                "[root] null_resource.example_resource" -> "[root] null_resource.example_resource (expand)"
                "[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)" -> "[root] module.test_module[\"a\"].null_resource.base (destroy deposed b1459d92)"
                "[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)"
        }
}

It seems like terraform is making a dependency from example_resource to test_module, when it should instead be making a dependency to test_module's outputs.

References

No response

@natedogith1 natedogith1 added bug new new issue not yet triaged labels Aug 9, 2024
@jbardin
Copy link
Member

jbardin commented Aug 12, 2024

Hi @natedogith1,

Thanks for filing the issue. Terraform has already made the precedent that referring to an entire module does cause a dependency on everything within that module. All references in Terraform resources are handled equally, so when connecting nodes there is no way to differentiate a reference to module.test_module which requires all edges be added, and one which could only make use of the available outputs.

In most cases this lack of differentiation is not visible to the user, but the create_before_destroy situation which forces the re-ordering of operations is a valid concern. We will have to look at increasing the granularity of these references to see if we can build a less conservative graph.

Thanks!

@jbardin jbardin added enhancement core and removed bug new new issue not yet triaged labels Aug 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants