Search for HCL(v2) using syntax tree.

The idea is heavily inspired by https://github.com/mvdan/gogrep.


go install github.com/magodo/[email protected]


usage: hclgrep pattern [files]

A pattern is a piece of HCL code which may include wildcards. It can be:

  • A body (zero or more attributes, and zero or more blocks)
  • An expression

There are two types of wildcards, depending on the scope it resides in:

  • Attribute wildcard (“@”): represents an attribute, a block, or an object element
  • Expression wildcard (“$”): represents an expression or a place that a string is accepted (i.e. as a block type, block label)

The wildcards are followed by a name. Each wildcard with the same name must match the same node/string, excluding “_”. Example:

$x.$_ = $x # assignment of self to a field in self

If “*” is before the name, it will match any number of nodes. Example:

[$*_] # any number of elements in a tuple

resource foo "name" {
    @*_  # any number of attributes/blocks inside the resource block body


$ hclgrep 'dynamic $_ {@*_}' main.tf            # Grep dynamic blocks used in Terraform config
$ hclgrep 'var.$_[count.index]' main.tf         # Grep potential mis-used "count" in Terraform config


  • The any expression wildcard ($*) doesn’t work inside a traversal.
  • The expression wildcard doesn’t work in place of traverse index. E.g. a[$_] doesn’t match a[1], as the index is a cty.Value.
  • The expression wildcard doesn’t work in place of unary/binary expression, as it compares by implementation and type (cty.Type).


View Github