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

tflint does not handle locals as expected #2169

Open
1 of 3 tasks
TrongBYM opened this issue Nov 20, 2024 · 1 comment
Open
1 of 3 tasks

tflint does not handle locals as expected #2169

TrongBYM opened this issue Nov 20, 2024 · 1 comment
Labels

Comments

@TrongBYM
Copy link

Summary

Hello, I am playing around with tflint and encountered an unexpected behaviour when it comes to local values.

I have a minimal example here: https://github.com/TrongBYM/tflint-issue-example

In short, I am running tflint against a Terraform configuration that provisions 3 ECR repositories, all with invalid ECR names. I therefore expects tflint to report 3 issues with my Terraform configuration, but instead it reports only 2 issues.

According to the documentation here about local values, this behaviour seems unexpected?

Is there a limitation I am not aware of here? I did find this list of caveats, with the first point looking rather related to this case.

Command

tflint

Terraform Configuration

# My project structure (see referenced example repository!)
# .
# ├── README.md
# ├── main.tf
# └── modules
#     └── custom_ecr
#         └── main.tf

### ./main.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0, < 6.0"
    }
  }
  required_version = "~> 1.8, < 2.0"
}

module "my_ecr_repository" {
  source   = "./modules/custom_ecr"
  ecr_name = "%%%"  # Invalid ECR repository name
}


### ./modules/custom_ecr/main.tf
variable "ecr_name" {
  type    = string
}

# NOTE: The character "%" is not allowed in ECR repository names.

# tflint will catch this error
resource "aws_ecr_repository" "this" {
  name = var.ecr_name 
}

# tflint will catch this error
resource "aws_ecr_repository" "this_too" {
  name = "${var.ecr_name}-hello-world" 
}

# tflint will NOT catch this error
locals {
  ecr_name_abstraction = "${var.ecr_name}-hello-world"
}
resource "aws_ecr_repository" "this_three" {
  name = local.ecr_name_abstraction
}

TFLint Configuration

config {
  plugin_dir = ".tflint.d/plugins"
  call_module_type = "all" # have tried "local" as well, same results!
  disabled_by_default = false
}

plugin "terraform" {
  enabled = true
  preset  = "recommended"
}

plugin "aws" {
  enabled = true
  deep_check = false 
  version = "0.35.0"
  source  = "github.com/terraform-linters/tflint-ruleset-aws"
}

Output

09:34:58 config.go:177: [INFO] Load config: .tflint.hcl
09:34:58 config.go:334: [DEBUG] Config loaded
09:34:58 config.go:335: [DEBUG]   CallModuleType: all
09:34:58 config.go:336: [DEBUG]   CallModuleTypeSet: true
09:34:58 config.go:337: [DEBUG]   Force: false
09:34:58 config.go:338: [DEBUG]   ForceSet: false
09:34:58 config.go:339: [DEBUG]   DisabledByDefault: false
09:34:58 config.go:340: [DEBUG]   DisabledByDefaultSet: true
09:34:58 config.go:341: [DEBUG]   PluginDir: .tflint.d/plugins
09:34:58 config.go:342: [DEBUG]   PluginDirSet: true
09:34:58 config.go:343: [DEBUG]   Format: 
09:34:58 config.go:344: [DEBUG]   FormatSet: false
09:34:58 config.go:345: [DEBUG]   Varfiles: 
09:34:58 config.go:346: [DEBUG]   Variables: 
09:34:58 config.go:347: [DEBUG]   Only: 
09:34:58 config.go:348: [DEBUG]   IgnoreModules:
09:34:58 config.go:352: [DEBUG]   Rules:
09:34:58 config.go:356: [DEBUG]   Plugins:
09:34:58 config.go:358: [DEBUG]     aws: enabled=true, version=0.35.0, source=github.com/terraform-linters/tflint-ruleset-aws
09:34:58 config.go:358: [DEBUG]     terraform: enabled=true, version=, source=
09:34:58 option.go:77: [DEBUG] CLI Options
09:34:58 option.go:78: [DEBUG]   CallModuleType: local
09:34:58 option.go:79: [DEBUG]   Force: false
09:34:58 option.go:80: [DEBUG]   Format: 
09:34:58 option.go:81: [DEBUG]   Varfiles: 
09:34:58 option.go:82: [DEBUG]   Variables: 
09:34:58 option.go:83: [DEBUG]   EnableRules: 
09:34:58 option.go:84: [DEBUG]   DisableRules: 
09:34:58 option.go:85: [DEBUG]   Only: 
09:34:58 option.go:86: [DEBUG]   EnablePlugins: 
09:34:58 option.go:87: [DEBUG]   IgnoreModules:
09:34:58 loader.go:39: [INFO] Initialize new loader
09:34:58 module_mgr.go:63: [INFO] Module manifest file found. Initializing...
09:34:58 loader.go:78: [INFO] Building the root module while calling child modules...
09:34:58 loader.go:108: [DEBUG] Trying to load the local module: name=my_ecr_repository dir=modules/custom_ecr
09:34:58 runner.go:46: [INFO] Initialize new runner for root
09:34:58 runner.go:46: [INFO] Initialize new runner for module.my_ecr_repository
09:34:58 discovery.go:33: [INFO] Plugin "terraform" is not installed, but the bundled plugin is available.
09:34:58 discovery.go:54: [INFO] Plugin "terraform" found
09:34:58 [DEBUG] cmdrunner/cmd_runner.go:73: starting plugin: path=/usr/local/bin/tflint args=["/usr/local/bin/tflint", "--act-as-bundled-plugin"]
09:34:58 [DEBUG] cmdrunner/cmd_runner.go:80: plugin started: path=/usr/local/bin/tflint pid=38028
09:34:58 [DEBUG] go-plugin@v1.6.2/client.go:827: waiting for RPC address: plugin=/usr/local/bin/tflint
09:34:58 [DEBUG] go-plugin@v1.6.2/client.go:1216: tflint: 09:34:58 [DEBUG] go-plugin@v1.6.2/server.go:419: plugin address: network=unix address=/tmp/plugin2381623722
09:34:58 [DEBUG] go-plugin@v1.6.2/client.go:880: using plugin: version=11
09:34:58 discovery.go:90: [DEBUG] Find plugin path: .tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-aws/0.35.0/tflint-ruleset-aws
09:34:58 discovery.go:54: [INFO] Plugin "aws" found
09:34:58 [DEBUG] cmdrunner/cmd_runner.go:73: starting plugin: path=.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-aws/0.35.0/tflint-ruleset-aws args=[".tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-aws/0.35.0/tflint-ruleset-aws"]
09:34:58 [DEBUG] cmdrunner/cmd_runner.go:80: plugin started: path=.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-aws/0.35.0/tflint-ruleset-aws pid=38038
09:34:58 [DEBUG] go-plugin@v1.6.2/client.go:827: waiting for RPC address: plugin=.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-aws/0.35.0/tflint-ruleset-aws
09:34:58 [DEBUG] go-plugin@v1.6.2/client.go:880: using plugin: version=11
09:34:58 [DEBUG] go-plugin@v1.6.2/client.go:1216: tflint-ruleset-aws: 09:34:58 [DEBUG] go-plugin@v1.6.1/server.go:419: plugin address: network=unix address=/tmp/plugin1597952239
09:34:58 [DEBUG] host2plugin/client.go:124: starting host-side gRPC server
09:34:58 [DEBUG] host2plugin/client.go:124: starting host-side gRPC server
09:34:58 [DEBUG] host2plugin/client.go:124: starting host-side gRPC server
09:34:58 [DEBUG] host2plugin/client.go:124: starting host-side gRPC server
09:34:58 [DEBUG] go-plugin@v1.6.2/grpc_stdio.go:142: stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
09:34:58 [INFO]  go-plugin@v1.6.2/client.go:780: plugin process exited: plugin=/usr/local/bin/tflint id=38028
09:34:58 [DEBUG] go-plugin@v1.6.2/client.go:558: plugin exited
09:34:58 [DEBUG] go-plugin@v1.6.2/grpc_stdio.go:142: stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
09:34:58 [INFO]  go-plugin@v1.6.2/client.go:780: plugin process exited: plugin=.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-aws/0.35.0/tflint-ruleset-aws id=38038
09:34:58 [DEBUG] go-plugin@v1.6.2/client.go:558: plugin exited
2 issue(s) found:

Error: "%%!"(MISSING) does not match valid pattern ^(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*$ (aws_ecr_repository_invalid_name)

  on main.tf line 13:
  13:   ecr_name = "%%%"  # Invalid ECR repository name

Callers:
   main.tf:13,14-19
   modules/custom_ecr/main.tf:9,10-22

Error: "%%!h(MISSING)ello-world" does not match valid pattern ^(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*$ (aws_ecr_repository_invalid_name)

  on main.tf line 13:
  13:   ecr_name = "%%%"  # Invalid ECR repository name

Callers:
   main.tf:13,14-19
   modules/custom_ecr/main.tf:14,10-39

TFLint Version

0.54.0

Terraform Version

No response

Operating System

  • Linux
  • macOS
  • Windows
@TrongBYM TrongBYM added the bug label Nov 20, 2024
@wata727
Copy link
Member

wata727 commented Nov 23, 2024

Thank you for reporting this. This seems to be a bug that occurred when local values ​​were supported.

Whether an issue in a child module (./modules/custom_ecr) is related to the module's input values (ecr_name) ​​is determined by whether the range of the reported expression includes the corresponding var.ecr_name variable.
https://github.com/terraform-linters/tflint/blob/v0.54.0/tflint/runner.go#L239

To fix this, we would need to check the local value in the expression to determine if it contains var.ecr_name. For that matter, perhaps similar bugs exist with count.*, each.*, dynamic blocks.

While it is possible to fix this bug in the short term, the inspection model for child modules makes excessive assumptions, so a redesign of the model as in terraform-linters/tflint-plugin-sdk#193 may be more effective.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants