hashicorp / hashicorp/terraform-plugin-sdk
Tristate boolean values
- 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
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