Skip to content

Conversation

@cx-artur-ribeiro
Copy link
Contributor

@cx-artur-ribeiro cx-artur-ribeiro commented Jan 14, 2026

Closes #7944

Reason for Proposed Changes

  • As nicely explained in the tagged issue, KICS couldn't parse or evaluate Terraform locals blocks, causing false positives when resources referenced local.* values. The parser treated these as unresolved references instead of evaluating them to their actual values, preventing proper payload formation and query analysis.
  • Terraform locals are module-scoped (directory-level) and can reference variables, other locals, and functions. They require dependency resolution since locals can reference each other, including forward references.
  • The implementation needs to somehow match how Terraform behaves. KICS does not "lint" files but to make sure we do the right decisions while parsing and building the payload file, we need to take into consideration some terraform principles regarding [local values](named values), such as:
    • Module-scoped locals (directory-level, not file-level);
    • Dependency resolution via topological sort for forward references
    • Duplicate detection (Terraform errors on duplicate locals)
    • Circular dependency detection (Terraform errors on cycles)

Proposed Changes

  • Integrate getLocals() in terraform.go after getInputVariables() so variables are available for local evaluation. Uses directory-level caching for O(n) performance similar to variables.go;
  • Add comprehensive test coverage:
    • Directory-scoped processing (all .tf files in a directory share locals namespace)
    • Topological sort for correct evaluation order
    • Duplicate detection during collection phase
    • Cycle detection during topological sortTest scenarios:
      • Simple file with locals inside;
      • Locals referencing variables;
      • Multiple locals blocks from a single file;
      • Empty cases for a file/directory without locals;
      • Directory level locals with caching;
      • Circular references (should error);
      • Cross-file references (module-wide scoping);
      • Forward references (evaluation order independence);
      • Duplicate locals (should error);
      • Subdirectory isolation (parent/child modules are independent);
      • Missing variable references (graceful degradation with placeholders);
      • Error handling similar to variables.go and data_source.go;
    • Organize test fixtures in separate directories for each scenario to ensure proper module isolation;

Validation against actual Terraform v1.14.3:

  • All valid scenarios pass terraform validate;
  • All error scenarios fail with matching error messages:
    • Duplicates: "Duplicate local value definition"
    • Circular: "Cycle: local.x, local.y"
    • Missing vars: Handled with warnings (appropriate for static analysis)
Terraform validate or init command error outputs

Duplicates


│ Error: Terraform encountered problems during initialisation, including problems
│ with the configuration, described below.

│ The Terraform configuration must be valid before initialization so that
│ Terraform can determine which modules and providers need to be installed.




│ Error: Duplicate local value definition

│ on file2.tf line 3, in locals:
│ 3: duplicate_name = "from_file2"

│ A local value named "duplicate_name" was already defined at
│ file1.tf:2,3-32. Local value names must be unique within a module.


│ Error: Duplicate local value definition

│ on file2.tf line 3, in locals:
│ 3: duplicate_name = "from_file2"

│ A local value named "duplicate_name" was already defined at
│ file1.tf:2,3-32. Local value names must be unique within a module.

Overrides


│ Error: Terraform encountered problems during initialisation, including problems
│ with the configuration, described below.

│ The Terraform configuration must be valid before initialization so that
│ Terraform can determine which modules and providers need to be installed.




│ Error: Duplicate local value definition

│ on override_locals_b.tf line 3, in locals:
│ 3: app_name = "overridden_name"

│ A local value named "app_name" was already defined at
│ override_locals_a.tf:2,3-26. Local value names must be unique within a
│ module.


│ Error: Duplicate local value definition

│ on override_locals_b.tf line 3, in locals:
│ 3: app_name = "overridden_name"

│ A local value named "app_name" was already defined at
│ override_locals_a.tf:2,3-26. Local value names must be unique within a
│ module.

Missing var


│ Error: Reference to undeclared input variable

│ on locals_with_missing_var.tf line 4, in locals:
│ 4: with_missing_var = var.nonexistent_variable

│ An input variable with the name "nonexistent_variable" has not been
│ declared. This variable can be declared with a variable
│ "nonexistent_variable" {} block.

terraform validate

│ Error: Cycle: local.circular_b (expand), local.circular_a (expand)


For more information:

I submit this contribution under the Apache-2.0 license.

@cx-artur-ribeiro cx-artur-ribeiro self-assigned this Jan 14, 2026
@github-actions github-actions bot added feature New feature terraform Terraform query labels Jan 14, 2026
@github-actions
Copy link
Contributor

kics-logo

KICS version: v2.1.18

Category Results
CRITICAL CRITICAL 0
HIGH HIGH 0
MEDIUM MEDIUM 0
LOW LOW 0
INFO INFO 0
TRACE TRACE 0
TOTAL TOTAL 0
Metric Values
Files scanned placeholder 1
Files parsed placeholder 1
Files failed to scan placeholder 0
Total executed queries placeholder 47
Queries failed to execute placeholder 0
Execution time placeholder 0

@github-actions github-actions bot added the query New query feature label Jan 15, 2026
@github-actions github-actions bot added the aws PR related with AWS Cloud label Jan 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aws PR related with AWS Cloud feature New feature query New query feature terraform Terraform query

Projects

None yet

Development

Successfully merging this pull request may close these issues.

False Positive: Metadata Label Is Invalid (bc3dabb6) for Terraform local variable interpolation

1 participant