Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

helper/schema: Add validation to prevent write-only attributes in set nested blocks #1427

Merged
merged 3 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/unreleased/BUG FIXES-20250218-172440.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: BUG FIXES
body: 'helper/schema: Fixed bug that allowed write-only attributes within set nested blocks.
Any attribute within a set nested block with `WriteOnly` set to `true` will now trigger an error message.'
time: 2025-02-18T17:24:40.023079-05:00
custom:
Issue: "1427"
5 changes: 5 additions & 0 deletions .changes/unreleased/NOTES-20250218-172625.yaml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have to repeat this changelog, but I'm not expressly against it 😆

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: NOTES
body: Write-only attribute support is in technical preview and offered without compatibility promises until Terraform 1.11 is generally available.
time: 2025-02-18T17:26:25.941391-05:00
custom:
Issue: "1375"
8 changes: 7 additions & 1 deletion helper/schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -975,7 +975,13 @@ func (m schemaMap) internalValidate(topSchemaMap schemaMap, attrsOnly bool) erro
case *Resource:
attrsOnly := attrsOnly || v.ConfigMode == SchemaConfigModeAttr

if v.Computed && schemaMap(t.SchemaMap()).hasWriteOnly() {
blockHasWriteOnly := schemaMap(t.SchemaMap()).hasWriteOnly()

if v.Type == TypeSet && blockHasWriteOnly {
return fmt.Errorf("%s: Set Block type cannot contain WriteOnly attributes", k)
}

if v.Computed && blockHasWriteOnly {
return fmt.Errorf("%s: Block types with Computed set to true cannot contain WriteOnly attributes", k)
}

Expand Down
8 changes: 4 additions & 4 deletions helper/schema/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5303,7 +5303,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) {
},
true,
},
"Set configuration block nested attribute with WriteOnly set returns no errors": {
"Set configuration block nested attribute with WriteOnly set returns error": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice that we already had tests for it!

map[string]*Schema{
"config_block_attr": {
Type: TypeSet,
Expand All @@ -5319,7 +5319,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) {
},
},
},
false,
true,
},
"List configuration block with ConfigModeAttr set, sub block nested attribute with WriteOnly set returns no errors": {
map[string]*Schema{
Expand Down Expand Up @@ -5350,7 +5350,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) {
false,
},

"Set configuration block with ConfigModeAttr set, sub block nested attribute with WriteOnly set returns no errors": {
"Set configuration block with ConfigModeAttr set, sub block nested attribute with WriteOnly set returns error": {
map[string]*Schema{
"block": {
Type: TypeSet,
Expand All @@ -5376,7 +5376,7 @@ func TestSchemaMap_InternalValidate(t *testing.T) {
},
},
},
false,
true,
},
"List computed block nested attribute with WriteOnly set returns error": {
map[string]*Schema{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ which should either use the value by making the appropriate change to the API or

The following are high level differences between `Required`/`Optional` arguments and write-only arguments:

- Write-only arguments can accept ephemeral and non-ephemeral values
- Write-only arguments can accept ephemeral and non-ephemeral values.

- Write-only arguments cannot be used with set attributes and set nested blocks.

- Write-only argument values are only available in the configuration. The prior state, planned state, and final state values for
write-only arguments should always be `null`.
Expand Down Expand Up @@ -51,6 +53,7 @@ write-only arguments should always be `null`.
- Cannot be used when `Default` is `specified`
- Cannot be used with `DefaultFunc`
- Cannot be used with aggregate schema types (e.g. `typeMap`, `typeList`, `typeSet`), but non-computed nested block types can contain write-only arguments.
- Cannot be used within a set nested block type.

## Retrieving Write-only Values

Expand Down
3 changes: 2 additions & 1 deletion website/docs/plugin/sdkv2/schemas/schema-behaviors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ resource "example_instance" "ex" {
- Cannot be used when `ForceNew` is `true`
- Cannot be used when `Default` is `specified`
- Cannot be used with `DefaultFunc`
- Cannot be used with aggregate schema types (e.g. `typeMap`, `typeList`, `typeSet`), but non-computed nested block types can contain write-only arguments.
- Cannot be used with aggregate schema types (e.g. `typeMap`, `typeList`, `typeSet`), but non-computed list nested block types can contain write-only arguments.
- Cannot be used within a set nested block type

`WriteOnly` should be used for arguments that handle secret values that do not need to be persisted in Terraform plan or state,
such as passwords, API keys, etc. Write-only argument values are not sent to Terraform and do not
Expand Down
Loading