Repository: opentofu/opentofu
File: internal/configs/named_values.go (Go)

Code before:
	"github.com/zclconf/go-cty/cty/convert"

	"github.com/opentofu/opentofu/internal/addrs"
)

// A consistent detail message for all "not a valid identifier" diagnostics.
const badIdentifierDetail = "A name must start with a letter or underscore and may contain only letters, digits, underscores, and dashes."

// Variable represents a "variable" block in a module or file.
type Variable struct {
	Name        string
	Description string
	Default     cty.Value

	// Type is the concrete type of the variable value.
	Type cty.Type
	// ConstraintType is used for decoding and type conversions, and may
	// contain nested ObjectWithOptionalAttr types.
	ConstraintType cty.Type
	TypeDefaults   *typeexpr.Defaults

	ParsingMode VariableParsingMode
	Validations []*CheckRule
	Sensitive   bool
	Deprecated  string

	DescriptionSet bool
	SensitiveSet   bool
	DeprecatedSet  bool

	// Nullable indicates that null is a valid value for this variable. Setting
	// Nullable to false means that the module can expect this variable to
	// never be null.
	Nullable    bool
	NullableSet bool

	DeclRange hcl.Range
}

func decodeVariableBlock(block *hcl.Block, override bool) (*Variable, hcl.Diagnostics) {
	v := &Variable{
		Name:      block.Labels[0],
		DeclRange: block.DefRange,
	}

	// Unless we're building an override, we'll set some defaults
	// which we might override with attributes below. We leave these
	// as zero-value in the override case so we can recognize whether
	// or not they are set when we merge.
	if !override {
		v.Type = cty.DynamicPseudoType

Review comment (security):
I checked the usage of `Sensitive` field, and I believe we have a few more places where we could use `Deprecated` field.

The first one is the interactive input. There are few options: let the user know the field is deprecated beforehand or even skip the interactive input if the field is deprecated. Not sure about the last one, however deprecation would mean we have another field, which should be used instead, and thus it makes sense to just skip the deprecated one. The functions I am referring to are [Local.interactivelyCollectVariables](https://github.com/opentofu/opentofu/blob/main/internal/backend/local/backend_local.go#L417) and [Meta.getInput](https://github.com/opentofu/opentofu/blob/main/internal/command/meta_config.go#L162).

The second one is JSON output mode. It includes the configuration part, which IMO should reflect the deprecation as well as other configured options. For example, here is a part of configuration planned into a file:

```terraform
module "mod" {
  source = "./mod"
  a = "b"
}
```

And this is a part of `tofu show --json planfile` command:

```json
    "root_module": {
      "module_calls": {
        "mod": {
          "source": "./mod",
          "expressions": {
            "a": {
              "constant_value": "b"
            }
          },
          "module": {
            "variables": {
              "a": {
                "default": "b"
              }
            }
          }
        }
      }
    }
  },
  ```
  
  What do you think?

Code after:
	"github.com/zclconf/go-cty/cty"
	"github.com/zclconf/go-cty/cty/convert"

	"github.com/opentofu/opentofu/internal/addrs"
)

// A consistent detail message for all "not a valid identifier" diagnostics.
const badIdentifierDetail = "A name must start with a letter or underscore and may contain only letters, digits, underscores, and dashes."

// Variable represents a "variable" block in a module or file.
type Variable struct {
	Name        string
	Description string
	Default     cty.Value

	// Type is the concrete type of the variable value.
	Type cty.Type
	// ConstraintType is used for decoding and type conversions, and may
	// contain nested ObjectWithOptionalAttr types.
	ConstraintType cty.Type
	TypeDefaults   *typeexpr.Defaults

	ParsingMode VariableParsingMode
	Validations []*CheckRule
	Sensitive   bool
	Deprecated  string

	DescriptionSet bool
	SensitiveSet   bool

	// Nullable indicates that null is a valid value for this variable. Setting
	// Nullable to false means that the module can expect this variable to
	// never be null.
	Nullable    bool
	NullableSet bool

	DeclRange hcl.Range
}

func decodeVariableBlock(block *hcl.Block, override bool) (*Variable, hcl.Diagnostics) {
	v := &Variable{
		Name:      block.Labels[0],
		DeclRange: block.DefRange,
	}

	// Unless we're building an override, we'll set some defaults
	// which we might override with attributes below. We leave these
	// as zero-value in the override case so we can recognize whether
	// or not they are set when we merge.
	if !override {
		v.Type = cty.DynamicPseudoType