terraform-linters / tflint

A Pluggable Terraform Linter
Mozilla Public License 2.0
4.98k stars 357 forks source link

Autofix fails when changing directories #1958

Closed wata727 closed 10 months ago

wata727 commented 10 months ago

Summary

Using --chdir (or --recursive) and --fix together may cause rule checks to fail due to HCL parsing errors. This is probably due to the plugin not being able to properly handle auto-fixed code.

Side note: I had a really hard time researching issues like this, so maybe more logging about autofixes would be helpful.

Command

tflint --chdir ./subdir --fix

Terraform Configuration

resource "google_compute_backend_service" "backend_service" {
  name                  = lookup(data.foo.bar, "b")
  load_balancing_scheme = "INVALID"
}

TFLint Configuration

config {
  disabled_by_default = true
}

plugin "google" {
  enabled = true
  version = "0.26.0"
  source  = "github.com/terraform-linters/tflint-ruleset-google"
}

rule "terraform_deprecated_lookup" {
  enabled = true
}

rule "google_compute_backend_service_invalid_load_balancing_scheme" {
  enabled = true
}

Output

16:37:09 config.go:171: [INFO] Load config: .tflint.hcl
16:37:09 config.go:335: [DEBUG] Config loaded
16:37:09 config.go:336: [DEBUG]   CallModuleType: local
16:37:09 config.go:337: [DEBUG]   CallModuleTypeSet: false
16:37:09 config.go:338: [DEBUG]   Force: false
16:37:09 config.go:339: [DEBUG]   ForceSet: false
16:37:09 config.go:340: [DEBUG]   DisabledByDefault: true
16:37:09 config.go:341: [DEBUG]   DisabledByDefaultSet: true
16:37:09 config.go:342: [DEBUG]   PluginDir:
16:37:09 config.go:343: [DEBUG]   PluginDirSet: false
16:37:09 config.go:344: [DEBUG]   Format:
16:37:09 config.go:345: [DEBUG]   FormatSet: false
16:37:09 config.go:346: [DEBUG]   Varfiles:
16:37:09 config.go:347: [DEBUG]   Variables:
16:37:09 config.go:348: [DEBUG]   Only:
16:37:09 config.go:349: [DEBUG]   IgnoreModules:
16:37:09 config.go:353: [DEBUG]   Rules:
16:37:09 config.go:355: [DEBUG]     terraform_deprecated_lookup: true
16:37:09 config.go:355: [DEBUG]     google_compute_backend_service_invalid_load_balancing_scheme: true
16:37:09 config.go:357: [DEBUG]   Plugins:
16:37:09 config.go:359: [DEBUG]     google: enabled=true, version=0.26.0, source=github.com/terraform-linters/tflint-ruleset-google
16:37:09 config.go:386: [INFO] The "terraform" plugin block is not found. Enable the plugin "terraform" automatically
16:37:09 option.go:85: [DEBUG] CLI Options
16:37:09 option.go:86: [DEBUG]   CallModuleType: local
16:37:09 option.go:87: [DEBUG]   Force: false
16:37:09 option.go:88: [DEBUG]   Format:
16:37:09 option.go:89: [DEBUG]   Varfiles:
16:37:09 option.go:90: [DEBUG]   Variables:
16:37:09 option.go:91: [DEBUG]   EnableRules:
16:37:09 option.go:92: [DEBUG]   DisableRules:
16:37:09 option.go:93: [DEBUG]   Only:
16:37:09 option.go:94: [DEBUG]   EnablePlugins:
16:37:09 option.go:95: [DEBUG]   IgnoreModules:
16:37:09 loader.go:39: [INFO] Initialize new loader
16:37:09 loader.go:81: [INFO] Building the root module while calling local child modules...
16:37:09 runner.go:46: [INFO] Initialize new runner for root
16:37:09 discovery.go:90: [DEBUG] Find plugin path: /home/codespace/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-google/0.26.0/tflint-ruleset-google
16:37:09 discovery.go:54: [INFO] Plugin "google" found
16:37:09 [DEBUG] cmdrunner/cmd_runner.go:73: starting plugin: path=/home/codespace/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-google/0.26.0/tflint-ruleset-google args=["/home/codespace/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-google/0.26.0/tflint-ruleset-google"]
16:37:09 [DEBUG] cmdrunner/cmd_runner.go:80: plugin started: path=/home/codespace/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-google/0.26.0/tflint-ruleset-google pid=4259
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:825: waiting for RPC address: plugin=/home/codespace/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-google/0.26.0/tflint-ruleset-google
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [DEBUG] go-plugin@v1.5.1/server.go:404: plugin address: network=unix address=/tmp/plugin1207676809
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:878: using plugin: version=11
16:37:09 discovery.go:90: [DEBUG] Find plugin path: /home/codespace/.tflint.d/plugins/tflint-ruleset-terraform
16:37:09 discovery.go:54: [INFO] Plugin "terraform" found
16:37:09 [TRACE] go-plugin@v1.6.0/grpc_stdio.go:134: stdio: waiting for stdio data
16:37:09 [DEBUG] cmdrunner/cmd_runner.go:73: starting plugin: path=/home/codespace/.tflint.d/plugins/tflint-ruleset-terraform args=["/home/codespace/.tflint.d/plugins/tflint-ruleset-terraform"]
16:37:09 [DEBUG] cmdrunner/cmd_runner.go:80: plugin started: path=/home/codespace/.tflint.d/plugins/tflint-ruleset-terraform pid=4267
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:825: waiting for RPC address: plugin=/home/codespace/.tflint.d/plugins/tflint-ruleset-terraform
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [DEBUG] go-plugin@v1.4.10/server.go:404: plugin address: network=unix address=/tmp/plugin1952441474
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:878: using plugin: version=11
16:37:09 [TRACE] go-plugin@v1.6.0/grpc_stdio.go:134: stdio: waiting for stdio data
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/GetVersionConstraint req=
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/ApplyGlobalConfig req="config:{rules:{key:\"google_compute_backend_service_invalid_load_balancing_scheme\"  value:{name:\"google_compute_backend_service_invalid_load_balancing_scheme\"  enabled:true}}  rules:{key:\"terraform_deprecated_lookup\"  value:{name:\"terraform_deprecated_lookup\"  enabled:true}}  disabled_by_default:true  fix:true}"
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [DEBUG] tflint/ruleset.go:66: Default plugin rules are disabled by default
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/GetConfigSchema req=
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/ApplyConfig req=content:{}
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/GetVersionConstraint req=
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/ApplyGlobalConfig req="config:{rules:{key:\"google_compute_backend_service_invalid_load_balancing_scheme\"  value:{name:\"google_compute_backend_service_invalid_load_balancing_scheme\"  enabled:true}}  rules:{key:\"terraform_deprecated_lookup\"  value:{name:\"terraform_deprecated_lookup\"  enabled:true}}  disabled_by_default:true  fix:true}"
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/GetConfigSchema req=
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/ApplyConfig req=content:{}
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [DEBUG] terraform/ruleset.go:67: Default plugin rules are disabled by default
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/GetName req=
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/GetRuleNames req=
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/GetName req=
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/GetRuleNames req=
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/GetSDKVersion req=
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/GetSDKVersion req=
16:37:09 [DEBUG] host2plugin/client.go:124: starting host-side gRPC server
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/Check req=runner:1
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/GetFiles req=
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/GetModuleContent req="schema:{blocks:{type:\"resource\"  label_names:\"type\"  label_names:\"name\"  body:{attributes:{name:\"load_balancing_scheme\"}  Mode:SCHEMA_MODE_DEFAULT}}  Mode:SCHEMA_MODE_DEFAULT}  option:{module_ctx:MODULE_CTX_TYPE_SELF  hint:{resource_type:\"google_compute_backend_service\"}  expand_mode:EXPAND_MODE_EXPAND}"
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/GetFile req="name:\"subdir/main.tf\""
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/EvaluateExpr req="option:{type:\"\\"string\\"\"  module_ctx:MODULE_CTX_TYPE_SELF}  expression:{bytes:\"\\"INVALID\\"\"  range:{filename:\"subdir/main.tf\"  start:{line:3  column:27  byte:140}  end:{line:3  column:36  byte:149}}}"
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/EmitIssue req="rule:{name:\"google_compute_backend_service_invalid_load_balancing_scheme\"  enabled:true  severity:SEVERITY_ERROR}  message:\"expected load_balancing_scheme to be one of [\\"EXTERNAL\\" \\"INTERNAL_SELF_MANAGED\\" \\"INTERNAL_MANAGED\\" \\"EXTERNAL_MANAGED\\" \\"\\"], got INVALID\"  range:{filename:\"subdir/main.tf\"  start:{line:3  column:27  byte:140}  end:{line:3  column:36  byte:149}}"
16:37:09 [DEBUG] host2plugin/client.go:124: starting host-side gRPC server
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/Check req=runner:1
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/GetFiles req=
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/GetModulePath req=
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/GetFiles req=
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/GetModulePath req=
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/EmitIssue req="rule:{name:\"terraform_deprecated_lookup\"  enabled:true  severity:SEVERITY_WARNING  link:\"https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.5.0/docs/rules/terraform_deprecated_lookup.md\"}  message:\"Lookup with 2 arguments is deprecated\"  range:{filename:\"subdir/main.tf\"  start:{line:2  column:27  byte:88}  end:{line:2  column:52  byte:113}}  fixable:true"
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/ApplyChanges req="changes:{key:\"subdir/main.tf\"  value:\"resource \\"google_compute_backend_service\\" \\"backend_service\\" {\n  name                  = data.foo.bar[\\"b\\"]\n  load_balancing_scheme = \\"INVALID\\"\n}\n\"}"
16:37:09 [DEBUG] host2plugin/client.go:124: starting host-side gRPC server
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/proto.RuleSet/Check req=runner:2
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/GetFiles req=
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/GetModuleContent req="schema:{blocks:{type:\"resource\"  label_names:\"type\"  label_names:\"name\"  body:{attributes:{name:\"load_balancing_scheme\"}  Mode:SCHEMA_MODE_DEFAULT}}  Mode:SCHEMA_MODE_DEFAULT}  option:{module_ctx:MODULE_CTX_TYPE_SELF  hint:{resource_type:\"google_compute_backend_service\"}  expand_mode:EXPAND_MODE_EXPAND}"
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/GetFile req="name:\"subdir/main.tf\""
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/EvaluateExpr req="option:{type:\"\\"string\\"\"  module_ctx:MODULE_CTX_TYPE_SELF}  expression:{bytes:\"cheme = \\"\"  range:{filename:\"subdir/main.tf\"  start:{line:3  column:27  byte:132}  end:{line:3  column:36  byte:141}}}"
16:37:09 [ERROR] interceptor/logging.go:18: failed to gRPC request: direction=plugin2host method=/proto.Runner/EvaluateExpr err="rpc error: code = InvalidArgument desc = subdir/main.tf:3,36-4,1: Invalid multi-line string; Quoted strings may not be split over multiple lines. To produce a multi-line string, either use the \n escape to represent a newline character or use the \"heredoc\" multi-line template syntax., and 1 other diagnostic(s)"
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [ERROR] interceptor/logging.go:18: failed to gRPC request: direction=host2plugin method=/proto.RuleSet/Check err="rpc error: code = Aborted desc = failed to check \"google_compute_backend_service_invalid_load_balancing_scheme\" rule: subdir/main.tf:3,36-4,1: Invalid multi-line string; Quoted strings may not be split over multiple lines. To produce a multi-line string, either use the \n escape to represent a newline character or use the \"heredoc\" multi-line template syntax., and 1 other diagnostic(s)"
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-terraform: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/plugin.GRPCController/Shutdown req=
16:37:09 [DEBUG] go-plugin@v1.6.0/grpc_stdio.go:142: stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
16:37:09 [INFO]  go-plugin@v1.6.0/client.go:780: plugin process exited: plugin=/home/codespace/.tflint.d/plugins/tflint-ruleset-terraform id=4267
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:558: plugin exited
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:1214: tflint-ruleset-google: 16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=host2plugin method=/plugin.GRPCController/Shutdown req=
16:37:09 [DEBUG] go-plugin@v1.6.0/grpc_stdio.go:142: stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: read unix @->/tmp/plugin1207676809: read: connection reset by peer"
16:37:09 [INFO]  go-plugin@v1.6.0/client.go:780: plugin process exited: plugin=/home/codespace/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-google/0.26.0/tflint-ruleset-google id=4259
16:37:09 [DEBUG] go-plugin@v1.6.0/client.go:558: plugin exited
Failed to check ruleset; failed to check "google_compute_backend_service_invalid_load_balancing_scheme" rule: subdir/main.tf:3,36-4,1: Invalid multi-line string; Quoted strings may not be split over multiple lines. To produce a multi-line string, either use the \n escape to represent a newline character or use the "heredoc" multi-line template syntax., and 1 other diagnostic(s)

TFLint Version

0.50.1

Terraform Version

No response

Operating System

wata727 commented 10 months ago

The important outputs are these:

16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/EvaluateExpr req="option:{type:\"\\"string\\"\"  module_ctx:MODULE_CTX_TYPE_SELF}  expression:{bytes:\"\\"INVALID\\"\"  range:{filename:\"subdir/main.tf\"  start:{line:3  column:27  byte:140}  end:{line:3  column:36  byte:149}}}"
...
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/ApplyChanges req="changes:{key:\"subdir/main.tf\"  value:\"resource \\"google_compute_backend_service\\" \\"backend_service\\" {\n  name                  = data.foo.bar[\\"b\\"]\n  load_balancing_scheme = \\"INVALID\\"\n}\n\"}"
...
16:37:09 [TRACE] interceptor/logging.go:15: gRPC request: direction=plugin2host method=/proto.Runner/EvaluateExpr req="option:{type:\"\\"string\\"\"  module_ctx:MODULE_CTX_TYPE_SELF}  expression:{bytes:\"cheme = \\"\"  range:{filename:\"subdir/main.tf\"  start:{line:3  column:27  byte:132}  end:{line:3  column:36  byte:141}}}"

The expression sent EvaluateExpr after autofix is cheme =" instead of "INVALID". This is obviously wrong because it's not a valid expression.