Skip to content

feat(terraform): prune resources outside the target block closure - #74

Open
PushTheLimit wants to merge 1 commit into
coder:coder/preview_v0_69from
PushTheLimit:preview/target-closure-eval
Open

feat(terraform): prune resources outside the target block closure#74
PushTheLimit wants to merge 1 commit into
coder:coder/preview_v0_69from
PushTheLimit:preview/target-closure-eval

Conversation

@PushTheLimit

Copy link
Copy Markdown

What

Add OptionWithResourceClosure(targetTypes []string) to the Terraform parser. When set, root-module resource blocks that are not reachable (via references) from the given target block types are dropped before evaluation. Default off, so existing callers are unaffected.

Why

EvaluateAll evaluates every resource and module in a module on each call. Callers that only need a subset of a module's output pay to evaluate resources whose values can never affect that output.

The concrete driver is coder/preview rendering a workspace form: it only needs coder_parameter / coder_workspace_preset / coder_workspace_tags and what they reference, but today the whole module graph is evaluated on every keystroke over the dynamic-parameters websocket. On a real Altana template this is ~2s of EvaluateAll per request; with this option it drops to ~0.16s locally (~12x), and the computed parameters, presets and tags are byte-identical.

How

  • Seed a frontier from the references of every block that is neither a resource nor an output (variables, locals, data sources, providers, module arguments, and the target blocks themselves).
  • Mark every resource reachable from that frontier, following references through resources that are themselves retained.
  • Drop root-module resources that are not marked. Non-resource blocks are always retained and submodules are evaluated in full.

Safety

The retained set is the transitive reference closure of everything whose value can flow into a target block, so a resource is excluded only when nothing a target block reads can reference it: the evaluated values of the target blocks are unchanged. The closure is conservative, a reference that cannot be resolved to a concrete block keeps the matching blocks. If no target block is present, nothing is pruned.

Testing

  • New resource_closure_test.go: an orphan resource is pruned, a resource referenced by a parameter transitively through a local is retained, and the parameter's computed default is unchanged. Also covers default-off and no-target-present.
  • Existing pkg/iac/scanners/terraform/parser suite passes unchanged.

Base branch

Targets coder/preview_v0_69 (the line coder/preview currently pins) so it can flow into the deployed preview build; happy to also land it on main.

EvaluateAll evaluates every resource and module in a module on each call.
Callers that only need a subset of a module's output (for example coder/preview,
which computes a workspace's input parameters) pay to evaluate resources whose
values can never affect that output.

OptionWithResourceClosure(targetTypes) restricts root-module evaluation to the
resource blocks reachable, via references, from the given target block types
(matched on a block's type label, e.g. "coder_parameter"). Every non-resource
block is retained and submodules are evaluated in full, so the computed values
of the target blocks are unchanged; only resources that nothing in the target
closure references are dropped. The closure is conservative: a reference that
cannot be resolved to a concrete block keeps the matching blocks, so a resource
is excluded only when nothing a target block reads can reference it. Empty
targetTypes disables the behavior (default).
@PushTheLimit
PushTheLimit force-pushed the preview/target-closure-eval branch from fa2a879 to 3916002 Compare August 25, 2026 21:30
PushTheLimit added a commit to PushTheLimit/preview that referenced this pull request Aug 25, 2026
Preview evaluates the entire Terraform module graph on every call, even though
rendering a workspace form only needs coder_parameter, coder_workspace_preset
and coder_workspace_tags (and what they reference). The resources a workspace
would create cannot feed those blocks, so evaluating them is wasted work that
dominates request latency on large templates.

Pass OptionWithResourceClosure with the three target block types so the parser
drops root-module resources that nothing in that closure references. On a real
template this cuts EvaluateAll from ~2s to ~0.16s (~12x) with byte-identical
parameters, presets and tags.

Depends on the OptionWithResourceClosure addition in the trivy fork
(coder/trivy#74). The trivy replace is temporarily pinned to that PR's commit;
it will be moved to the merged coder/trivy commit before this merges.
@PushTheLimit
PushTheLimit marked this pull request as ready for review August 26, 2026 04:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant