Since your goal is to edit configuration, I think the best way to get this done is using the
hclwrite package, which is designed to allow you to work directly with HCL native syntax constructs.
gohcl, by contrast, is for decoding HCL data into normal Go values, which requires expression evaluation as you’ve seen. Also, reading data into
gohcl and then writing it out again will be lossy, because the Go data structures can’t preserve details like the ordering of the arguments in the input, any comments that are present, etc.
hclwrite package isn’t as mature as HCL’s main parser/decoder because none of the major applications using HCL 2 have needed it yet, but I did personally use it in a side-project related to Terraform and it seems to be broadly working, notwithstanding some edge-cases you can see in the issues in that repository at the time of writing.
I think you could do what you want here with the following steps using
- Read one
.tf file using
hclwrite.ParseConfig, producing an
- Use the
Body method on that object to obtain the root body of the file. (That is, the construct containing the top-level blocks.)
- Iterate over the result of the
Blocks method to visit each of the blocks in the file in turn:
Block.Type() to get the block type, and
continue if the result is anything other than
"resource", since you said you want to remove resources.
Block.Labels() to get the labels for the block, which for a Terraform
resource block will be a pair of strings: the resource type name and the resource name. (If you want to be robust against invalid input here, you should check first to make sure the result has length 2.)
- Check whether the two labels match the pattern you are looking for. If not,
Body.RemoveBlock on the main body, passing in the current block, to remove it.
- Finally, call
File.Bytes() on the original file (now modified in-place by the work so far) to obtain the modified source code. You could perhaps check if it’s different than what you originally loaded and overwrite the original file with the new content if so.
If you want to process an entire module, you can repeat the above for each
.tf file in a directory. The side-project I mentioned earlier might serve as a good starting-point, because it also works with all of the
.tf files in a particular directory and so maybe you can just replace the
cleanBody function with your own logic like the above to get something working quickly.
hclwrite package’s types encapsulate the raw tokens that an input file is built from and provider a higher-level API for manipulating it, which has the advantage that if you don’t modify a particular body at all then it will be preserved exactly, aside from whitespace changes caused by the pretty-printer. In particular, it will preserve any comments in the unmodified regions, and retain the ordering of attributes within the blocks, both of which would usually be discarded during normal HCL parsing.