Search code examples
terraformhcl

How to parse Terraform with sensitive variables


We are using gohcl.DecodeBody to parse Terraform scripts such as this one that marks variables as sensitive. We are not passing in an EvalContext:

diags := gohcl.DecodeBody(file.Body, nil, &root)

However this results in a diagnostic error:

2022/12/01 10:40:51 - .envbuilderTmpDir/github.com/terraform-ibm-modules/terraform-ibm-toolkit-resource-group/variables.tf:4,3-12: Unsupported argument; An argument named "sensitive" is not expected here.

As I read the docs, I think we need to pass in an EvalContext so the decoder can handle the sensitive attribute, but I'm not sure how to construct it. We don't really care about the sensitive attribute; we'd be fine if we could tell the decoder to ignore it. I've tried passing an empty one but I get the same error.


Solution

  • This error is reporting that the given schema does not declare an argument named sensitive.

    When you are using the gohcl abstraction to decode HCL the schema is inferred automatically using reflection against the type of the value you passed in to the last argument. That means that the schema will be decided based on whatever type you've declared for your variable root, which you didn't show in your question.

    To make your program accept an argument called sensitive inside variable blocks, you will need to identify which struct type in your program is representing variable blocks and add an extra field to it which is tagged to represent that it represents an argument called sensitive:

    type VariableBlock struct {
        // ...
        Sensitive hcl.Expression `hcl:"sensitive"`
    }
    

    I chose the target type hcl.Expression here because you mentioned in your question that you don't plan to actually make use of the sensitive argument value. Decoding into hcl.Expression means that gohcl will just capture directly whatever expression was assigned to sensitive without performing any further type checking or type conversion.

    If you did want to make use of the sensitive value in your program then you might prefer to decode into a Go bool field instead, which would then cause gohcl to require that the given value be a HCL boolean value and will convert it into a Go bool value to assign into the result.

    Note that Terraform itself doesn't use the gohcl package, so you won't be able to implement all aspects of the Terraform language through that abstraction. Depending on your goals, you may find it better to use the higher-level library terraform-config-inspect, which encapsulates the HCL-related details of the Terraform language and exposes only a subset of the language at a higher level of abstraction that's more appropriate for building certain kinds of tools for working with Terraform modules.