terraform-linters / tflint-ruleset-terraform

TFLint ruleset for Terraform Language
Mozilla Public License 2.0
61 stars 21 forks source link

terraform_deprecated_index emits multiple issues for same attribute #84

Closed MaxymVlasov closed 1 year ago

MaxymVlasov commented 1 year ago

Summary

Looks like TFlint separates local.kubernetes_namespace definition to all possible programming branches, execute them it TF way (executing true and false both), and then just sends all found errors without deduplication

Because:

Command

tflint

Terraform Configuration

terraform {
  required_version = "~> 1.3"
}

variable "kubernetes_namespace" {
  type        = string
  description = "The namespace to install the release into."
}

locals {
  create_namespace = true

  kubernetes_namespace = local.create_namespace ? join("", kubernetes_namespace.default.*.id) : var.kubernetes_namespace

}

output "kubernetes_namespace" {
  description = "."
  value = local.kubernetes_namespace
}

TFLint Configuration

It reproduced without any TFlint configs too.

# Required `tflint --init`
plugin "aws" {
    enabled    = true
    deep_check = false # Enabled only in CI: .spacelift/config.yml
    version    = "0.21.2"
    source     = "github.com/terraform-linters/tflint-ruleset-aws"
}

#
# https://github.com/terraform-linters/tflint/tree/master/docs/rules
#

rule "terraform_comment_syntax" {
    # Disallow `//` comments in favor of `#`
    enabled = true
}
rule "terraform_deprecated_index" {
    # Disallow legacy dot index syntax
    enabled = true
}
rule "terraform_deprecated_interpolation" {
    # Disallow deprecated (0.11-style) interpolation
    # Enabled by default
    enabled = true
}
rule "terraform_documented_outputs" {
    # Disallow output declarations without description
    enabled = true
}
rule "terraform_documented_variables" {
    # Disallow variable declarations without description
    enabled = true
}
rule "terraform_module_pinned_source" {
    # Disallow specifying a git or mercurial repository as a module source without pinning to a version
    # Enabled by default
    enabled = true
}
rule "terraform_module_version" {
    # Checks that Terraform modules sourced from a registry specify a version
    # Enabled by default
    enabled = true
}
rule "terraform_naming_convention" {
    # Enforces naming conventions for resources, data sources, etc
    enabled = true
}
rule "terraform_required_providers" {
    # Require that all providers have version constraints through required_providers
    enabled = true
}
rule "terraform_required_version" {
    # Disallow terraform declarations without require_version
    enabled = true
}
rule "terraform_standard_module_structure" {
    # Ensure that a module complies with the Terraform Standard Module Structure
    enabled = false # TODO p4: enable and fix
}
rule "terraform_typed_variables" {
    # Disallow variable declarations without type
    enabled = true
}
rule "terraform_unused_declarations" {
    # Disallow variables, data sources, and locals that are declared but never used
    enabled = true
}
rule "terraform_unused_required_providers" {
    # Check that all required_providers are used in the module
    enabled = true
}
rule "terraform_workspace_remote" {
    # terraform.workspace should not be used with a "remote" backend with remote execution.
    # Enabled by default
    enabled = true
}
rule "aws_db_instance_invalid_parameter_group" {
    # TODO: Figure out requirements to turn this back on; not sure it's providing value even as is due to AWS multi-account arch.
    enabled = false
}
config {
    variables = ["namespace=fake-namespace", "stage=fake-stage", "name=fake-name"]
}

Output

4 issue(s) found:

Warning: List items should be accessed using square brackets (terraform_deprecated_index)

  on main.tf line 14:
  14:   kubernetes_namespace = local.create_namespace ? join("", kubernetes_namespace.default.*.id) : var.kubernetes_namespace

Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.2.2/docs/rules/terraform_deprecated_index.md

Warning: List items should be accessed using square brackets (terraform_deprecated_index)

  on main.tf line 14:
  14:   kubernetes_namespace = local.create_namespace ? join("", kubernetes_namespace.default.*.id) : var.kubernetes_namespace

Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.2.2/docs/rules/terraform_deprecated_index.md

Warning: List items should be accessed using square brackets (terraform_deprecated_index)

  on main.tf line 14:
  14:   kubernetes_namespace = local.create_namespace ? join("", kubernetes_namespace.default.*.id) : var.kubernetes_namespace

Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.2.2/docs/rules/terraform_deprecated_index.md

Warning: List items should be accessed using square brackets (terraform_deprecated_index)

  on main.tf line 14:
  14:   kubernetes_namespace = local.create_namespace ? join("", kubernetes_namespace.default.*.id) : var.kubernetes_namespace

Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.2.2/docs/rules/terraform_deprecated_index.md

TFLint Version

0.45.0

Terraform Version

1.3.9

Operating System

wata727 commented 1 year ago

This is an issue with the terraform_deprecated_index rule. The WalkExpression function walks expressions recursively, as documented: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.2.2/rules/terraform_deprecated_index.go#L56 https://pkg.go.dev/github.com/terraform-linters/tflint-plugin-sdk@v0.15.0/tflint#Runner

The check is probably performed 4 times, including the expressions inside local.create_namespace ? join("", kubernetes_namespace.default.*.id) : var.kubernetes_namespace.