hashicorp / hashicorp/terraform-plugin-sdk

Tristate boolean values

Open
#817 11 comments 16 reactions 0 assignees View on GitHub
enhancement terraform-plugin-framework
Dominant language
Go
Stars
485
Forks
244
Avg merge
19h 57m
Merged PRs (30d)
4

Description

### SDK version

v2

### Use-cases

A common issue I've had to work around in the past is optional booleans capable of a true, false and uninitialised state. This usually comes around with HTTP PUT requests where you build the entirety of the payload and send it to an endpoint. This becomes even more tricky when the Terraform configuration block is optional/conditional and not always applied. Example

(explicitly enable a feature)

```hcl
resource "..." "..." {
example_attr = "foo"
enabled = "true"
}
```

(explicitly disable a feature)

```hcl
resource "..." "..." {
example_attr = "foo"
enabled = "false"
}
```

(uninitialised value and should not be sent in a payload)

```hcl
resource "..." "..." {
example_attr = "foo"
}
```

All three of these examples would behave differentially using HTTP PUT. The example above is rather simple but does quickly grow in unnecessary workarounds and complexity of providers when you start nesting the schema attributes.

### Attempted Solutions

In general, we have used attributes with a `Optional` field in the schema and relied on `d.GetOkExists` however that functionality has since been [deprecated](https://github.com/hashicorp/terraform-plugin-sdk/blob/5f6ea40c13d0eaade9263ba96439c9be93eeeb13/helper/schema/resource_data.go#L102-L111) with no real alternative available. Another approach we've used is a boolean pointer in the underlying library for the API however it still relies on some functionality in the provider itself to determine whether to set it or not.

### Proposal

I'm not quite sure how it would be implemented, or even if it is possible, however something like a tristate boolean value in go-cty would be great. The values would be `true`, `false` and `unset`/`uninitialised` which would allow like for like functionality with (I _think_) most of the `d.GetOkExists` wants in a reliable fashion.

The solution would also need to be able to "unset" a value in Terraform should a method be called on the value in order to satisfy the need where a value is set as `true`/`false` but later returned to an uninitialised state.

### References

None that I found.

Contributor guide

Open the contributing guide

Research direction

Start by reading helper/schema/resource_data.go around the deprecated GetOkExists behavior. Trace how optional boolean values are represented and consumed in the SDK, then identify the tests needed to distinguish true, false, and unset states. Done means the supported behavior and reset-to-unset semantics are defined and verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, terraform
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.