Skip to content

feat: support Terraform override files in template preview#196

Open
geokat wants to merge 4 commits intomainfrom
george/override-file-support-pre-eval
Open

feat: support Terraform override files in template preview#196
geokat wants to merge 4 commits intomainfrom
george/override-file-support-pre-eval

Conversation

@geokat
Copy link

@geokat geokat commented Mar 4, 2026

Implements https://developer.hashicorp.com/terraform/language/files/override semantics (override.tf, *_override.tf) by merging override blocks into primary .tf files before Trivy evaluation:

  • Override attributes replace primary attributes; override child blocks (including options, parameters, presets and variables) replace all primary blocks of the same type - matching Terraform's prepareContent behavior
  • Introduces overrideFS, an in-memory fs.FS wrapper that serves merged content and hides consumed override files from downstream consumers

How it works

  1. mergeOverrideFiles walks the filesystem, separating primary and override files per directory
  2. Override files are processed sequentially (lexicographic order), each merging into the already-merged primary using hclwrite
  3. The resulting overrideFS serves merged primary files and hides override files, so Trivy sees clean, post-merge HCL with no duplicate blocks
  4. No-op when no override files are present - the original fs.FS is returned unchanged, so existing templates without overrides are completely unaffected

Related to: coder/coder#21991

geokat added 2 commits March 3, 2026 18:06
Implement Terraform's override file semantics (override.tf, *_override.tf)
by merging override blocks into primary files before evaluation.

Related to: coder/coder#21991
@geokat geokat marked this pull request as ready for review March 4, 2026 02:38
@geokat geokat requested a review from Emyrk March 4, 2026 02:38
Comment on lines +213 to +217
// Merge override files into primary files before parsing, so Trivy
// sees post-merge content with no duplicate blocks. This replicates
// Terraform's override file semantics.
//
// TODO: It'd be nice if Trivy did this for us.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Crazy they do not 😢

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I now know why :)

f, diags := hclwrite.ParseConfig(content, path, hcl.Pos{Line: 1, Column: 1})
if diags.HasErrors() {
return nil, fmt.Errorf("parse file %s: %s", path, diags.Error())
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this only works for .hcl files. hclparse can do json. Idk if that is the same format or transferable to hclwrite though.

import "github.com/hashicorp/hcl/v2/hclparse"

p := hclparse.NewParser()
p.ParseJSONFile()

As it stands, json files will break this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great catch!

After some research, supporting .tf.json files is more complex than it looks. hclparse's structs can't be used with hclwrite and there's no straightforward way to convert between the two. And JSON is ambiguous about blocks vs attributes, so there's no way to resolve this without the provider schema. So even Trivy doesn't do that :)

For now I'm thinking of not merging at all if .tf.json files are detected - maybe issue a warning about the lack of support and hope the override stuff is not coder-related. Or only merge the .tf files and warn that .tf.json overrides are not supported.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can issue a warning, do it. Otherwise a silent drop is fine for json imo

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.

2 participants