terraform-linters / tflint-ruleset-terraform

TFLint ruleset for Terraform Language
Mozilla Public License 2.0
65 stars 24 forks source link

`terraform_map_duplicate_keys`: declaration in for expression fails to be processed #199

Closed gnuletik closed 3 months ago

gnuletik commented 3 months ago

Since latest version (v0.9.0), tflint raise an error with the following (valid) code

variable "allowed_security_group_ids" {
  type        = list(string)
  description = "The allowed security group IDs"
  default     = []
}

locals {
  rules = merge(
    [for sg_id in var.allowed_security_group_ids : {
      "ingress_${sg_id}_http" = {
        from_port                    = 80
        to_port                      = 80
        ip_protocol                  = "tcp"
        description                  = "HTTP web traffic"
        referenced_security_group_id = sg_id
      }
      "ingress_${sg_id}_https" = {
        from_port                    = 443
        to_port                      = 443
        ip_protocol                  = "tcp"
        description                  = "HTTPS web traffic"
        referenced_security_group_id = sg_id
      }
    }]...
  )
}
Failed to check ruleset; failed to check "terraform_map_duplicate_keys" rule: <nil>: failed to evaluate expression; alb-internal.tf:20,18-23: Invalid reference; A reference to a resource type must be followed by at least one attribute access, specifying the resource name., and 1 other diagnostic(s)
wata727 commented 3 months ago

Thank you for reporting this. This seems like an edge case.

Currently, this rule walks all expressions in a configuration file and evaluates the keys, but expressions in different scopes, such as for expressions, cannot be statically evaluated. This is because the value of "ingress_${sg_id}_http" is not unique.

Ideally, we could expand the for expression before walking expressions, so we could check for all possible keys, but this is difficult to do in the current SDK features. Given this, the easiest fix we can make right now might be to just ignore the key if it fails evaluation.