terraform-linters / tflint

A Pluggable Terraform Linter
Mozilla Public License 2.0
4.88k stars 354 forks source link

Add support for evaluating static module outputs #2076

Open wata727 opened 3 months ago

wata727 commented 3 months ago

Introduction

TFLint cannot statically evaluate dynamic values ​​like aws_instance.test.id, so these values ​​are ignored. Similarly, module outputs (e.g. module.aws_instance.id) are also marked as dynamic values.

resource "aws_lb_target_group_attachment" "test" {
  target_id = module.aws_instance.id # => ignored
}

However, module outputs are not always dynamic values. Modules that are used to share variables across multiple modules may have outputs that are statically determinable.

resource "aws_instance" "test" {
  tags = module.shared.tags # => This is a static value, but it cannot be evaluated by TFLint.
}

Proposal

Add support for evaluating static module outputs.

Currently, all module.* named values ​​resolve to unknown values.

https://github.com/terraform-linters/tflint/blob/a7179f0f8ba9a4d56f8a688949aa304bf3b5f351/terraform/lang/eval.go#L214

If call_module_type is other than none and the child module's sources are accessible, then the output of the child module that corresponds to the address reference will be evaluated when generating the evaluation context. This might be similar to evaluating local values.

https://github.com/terraform-linters/tflint/blob/a7179f0f8ba9a4d56f8a688949aa304bf3b5f351/terraform/evaluator.go#L227-L268

If the value cannot be evaluated at any point, for example because the source of the grandchild module is inaccessible, an unknown value will be returned as before.

References

omasopust commented 1 week ago

This is exactly what we are missing right now.

We are passing a module output containing a map of tags to the AWS provider default_tags and we want to use aws_provider_missing_default_tags rule to enforce this. Unfotunately, as the OP stated, any module output is ignored and the rule is not picking up the tags set by the module output.