Visitar URL original
bug: dynamic parameters skip every module after one that receives a random_* value · Issue #30056 · coder/coder · GitHub
Skip to content

bug: dynamic parameters skip every module after one that receives a random_* value #30056

Description

@PushTheLimit

Summary

When a template passes a random_* value (for example random_password.x.result) into a module, the dynamic parameters form does not evaluate any module declared after it. Parameters defined in those modules silently disappear from the form, and each one is reported as Module not loaded. Did you run terraform init?. Every render also runs the evaluator's full 32 passes, so the form gets slow on large templates.

Reproduction

main.tf:

terraform {
  required_providers {
    coder = {
      source = "coder/coder"
    }
  }
}

resource "random_password" "secret" {
  length = 12
}

module "a_secret" {
  source = "./modules/sink"
  value  = random_password.secret.result
}

module "b_region" {
  source = "./modules/param"
}

modules/sink/main.tf:

variable "value" {
  type = string
}

resource "terraform_data" "sink" {
  input = var.value
}

modules/param/main.tf:

data "coder_parameter" "region" {
  name    = "region"
  type    = "string"
  default = "us"
}

Rendering this with preview.Preview at the versions main pins (coder/preview c0dfdeecbd89, coder/trivy 15b949537506):

params=[]
diag: Module not loaded. Did you run `terraform init`? | Module 'module "b_region"' in file "main.tf:18,1-18" cannot be resolved. This module will be ignored.

Expected: params=[region] and no diagnostic. Replacing the module input with a plain string gives the expected result.

Cause

Two things in the coder/trivy evaluator combine:

  1. createPresetValues (pkg/iac/terraform/presets.go) gives random_password, random_string, random_id, random_bytes, random_uuid and random_integer a new uuid.New() / rand.Int64() value on every call, and it runs on every evaluation pass. Anything outside a resource that reads one of them never settles, so evaluateSteps never sees an unchanged context and always runs maxContextIterations passes.
  2. evaluateSubmodules (pkg/iac/scanners/terraform/parser/evaluator.go) does changed = changed || e.evaluateSubmodule(ctx, sm). Once one submodule reports a change, || short-circuits and skips every submodule after it in that pass. A submodule fed a random value reports a change on every pass, so the modules after it are never evaluated in any pass. coder/preview then flags them as not loaded.

This is not the same as coder/preview#228, where the module is evaluated and the warning is a false positive. Here the module's blocks and parameters are really missing.

On a large production template (about 60 resources and a dozen modules) this took a parameter render from about 0.35s to 3.2s, and the form showed "Module not loaded" for 11 modules.

Fix

A PR against coder/trivy follows: evaluate every submodule on each pass, and derive the random_* placeholders from the block so they are stable across passes.

Activity

  1. linear-code commented on Sep 28, 2026

    @linear-code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions