Skip to content

Commit

Permalink
Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Austin Valle <[email protected]>
  • Loading branch information
SBGoods and austinvalle authored Jan 24, 2025
1 parent 1b935c4 commit 5070aeb
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .changes/unreleased/FEATURES-20250121-165644.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
kind: FEATURES
body: 'helper/schema: Added `WriteOnly` schema behavior for managed resource schemas to indicate a write-only attribute.
Write-only attributes are managed resource attributes whose values are not saved to the Terraform plan or state artifacts.'
Write-only attribute values are not saved to the Terraform plan or state artifacts.'
time: 2025-01-21T16:56:44.038893-05:00
custom:
Issue: "1375"
2 changes: 1 addition & 1 deletion helper/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ type Schema struct {
Sensitive bool

// WriteOnly indicates that the practitioner can choose a value for this
// attribute, but Terraform will not store this attribute in state.
// attribute, but Terraform will not store this attribute in plan or state.
// WriteOnly can only be set for managed resource schemas. If WriteOnly is true,
// either Optional or Required must also be true. WriteOnly cannot be set with ForceNew.
//
Expand Down
4 changes: 2 additions & 2 deletions helper/schema/write_only.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ func validateWriteOnlyNullValues(val cty.Value, schema *configschema.Block, path
if attr.WriteOnly && !v.IsNull() {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: "WriteOnly Attribute Not Allowed",
Detail: fmt.Sprintf("The resource contains a non-null value for WriteOnly attribute %q ", name) +
Summary: "Write-only Attribute Not Allowed",
Detail: fmt.Sprintf("The resource contains a non-null value for write-only attribute %q ", name) +
"Write-only attributes are only supported in Terraform 1.11 and later.",
AttributePath: append(path, cty.GetAttrStep{Name: name}),
})
Expand Down
2 changes: 1 addition & 1 deletion internal/configs/configschema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ type Attribute struct {
Deprecated bool

// WriteOnly indicates that the practitioner can choose a value for this
// attribute, but Terraform will not store this attribute in state.
// attribute, but Terraform will not store this attribute in plan or state.
// WriteOnly can only be set for managed resource schemas. If WriteOnly is true,
// either Optional or Required must also be true. WriteOnly cannot be set with ForceNew.
//
Expand Down
6 changes: 3 additions & 3 deletions website/docs/plugin/sdkv2/resources/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ When resource implementations change (due to bug fixes, improvements, or changes

~> **NOTE:** Write-only attributes are only supported in Terraform `v1.11` or higher

Write-only attributes are a special type of resource attribute
whose values are not sent to Terraform and do not persist in the Terraform plan or state artifacts.
Write-only attributes can accept [ephemeral values](/terraform/language/resources/ephemeral).
Write-only attributes are a special type of managed resource attribute
that are configured by practitioners but are not persisted in the Terraform plan or state artifacts.
Write-only attributes can accept [ephemeral values](/terraform/language/resources/ephemeral) and are not required to be consistent between plan and apply operations..
The [Write-only attribute] page discusses how to create these attributes.
24 changes: 12 additions & 12 deletions website/docs/plugin/sdkv2/resources/write-only-attributes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ description: Implementing write-only attributes within resources.

~> **NOTE:** Write-only attributes are only supported in Terraform `v1.11` or higher

Write-only attributes are managed resource attributes whose values are not saved to the Terraform plan or state artifacts. Write-only attributes
Write-only attributes are managed resource attributes that are configured by practitioners but are not persisted to the Terraform plan or state artifacts. Write-only attributes
should be used to handle secret values that do not need to be persisted in Terraform state, such as passwords, API keys, etc.
The provider is expected to be the terminal point for an ephemeral value,
which should either use the value by making the appropriate change to the API or ignore the value. Write-only attributes can accept [ephemeral values](/terraform/language/resources/ephemeral).
which should either use the value by making the appropriate change to the API or ignore the value. Write-only attributes can accept [ephemeral values](/terraform/language/resources/ephemeral) and are not required to be consistent between plan and apply operations.

## General Concepts

The following are high level differences between regular attributes and write-only attributes:

- Write-only attributes can accept ephemeral and non-ephemeral values

- Write-only attribute values are only available in the configuration, and the prior state, planned state, and final state values for
- Write-only attribute values are only available in the configuration. The prior state, planned state, and final state values for
write-only attributes should always be `null`.
- Provider developers do not need to “clean up” write-only attribute values after using them as the SDKv2 will handle the nullification of write-only attributes for all RPCs.
- Provider developers do not need to explicitly set write-only attribute values to `null` after using them as the SDKv2 will handle the nullification of write-only attributes for all RPCs.

- Any value that is set for a write-only attribute using `(*ResourceData).Set()` by the provider will be set to `null` by SDKv2 before the RPC response is sent to Terraform
- Any value that is set for a write-only attribute using `(*ResourceData).Set()` by the provider will be reverted to `null` by SDKv2 before the RPC response is sent to Terraform

- Write-only attribute values on its own will never cause a Terraform diff.
- Write-only attribute values cannot produce a Terraform plan difference.
- This is because the prior state value for a write-only attribute will always be `null` and the planned/final state value will also be `null`, therefore, it cannot produce a diff on its own.
- The one exception to this case is if the write-only attribute is added to `requires_replace` via [CustomizeDiff](/terraform/plugin/sdkv2/resources/customizing-differences), in that case, the write-only attribute will always cause a diff/trigger a resource recreation

Expand Down Expand Up @@ -112,7 +112,7 @@ Index(cty.ObjectVal(map[string]cty.Value{"set_nested_block_attribute": cty.Strin

### cty.Value

When working with `cty.Value`, you must always check the type of the value before converting it to a Go value or else the conversion will cause a panic.
When working with `cty.Value`, you must always check the type of the value before converting it to a Go value or else the conversion could cause a panic.

```go
// Check that the type is a cty.String before conversion
Expand All @@ -127,9 +127,9 @@ if !woVal.IsNull() {
}
```

## PreferWriteOnly Validator
## PreferWriteOnlyAttribute Validator

`PreferWriteOnlyAttribute()` is a validator that takes a `cty.Path` to a regular attribute and a `cty.Path` to a write-only attribute.
`PreferWriteOnlyAttribute()` is a validator that takes a `cty.Path` to an existing configuration attribute (required/optional) and a `cty.Path` to a write-only attribute.

Use this validator when you have a write-only version of an existing attribute, and you want to encourage practitioners to use the write-only version whenever possible.

Expand Down Expand Up @@ -170,8 +170,8 @@ When using `cty.Path` to traverse into a nested block, use an unknown value to i

## Best Practices

Since write-only attributes have no prior values, we cannot determine user intent with a write-only attribute alone. To determine when to use/not use a write-only attribute value in your provider, we recommend using other attributes in the provider. For example:
Since write-only attributes have no prior values, user intent cannot be determined with a write-only attribute alone. To determine when to use/not use a write-only attribute value in your provider, we recommend using other non-write-only attributes in the provider. For example:

- Pair write-only attributes with a regular attribute to “trigger” the use of the write-only attribute
- For example, a `password_wo` write-only attribute can be paired with a configured `password_wo_version` attribute. When the `password_wo_version` updates, the provider will send the `password_wo` value to the API.
- Pair write-only attributes with a configuration attribute (required or optional) to “trigger” the use of the write-only attribute
- For example, a `password_wo` write-only attribute can be paired with a configured `password_wo_version` attribute. When the `password_wo_version` is modified, the provider will send the `password_wo` value to the API.
- Use a keepers attribute (which is used in the [Random Provider](https://registry.terraform.io/providers/hashicorp/random/latest/docs#resource-keepers)) that will take in arbitrary key-pair values. Whenever there is a change to the `keepers` attribute, the provider will use the write-only attribute value.

0 comments on commit 5070aeb

Please sign in to comment.