Skip to content
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
5 changes: 5 additions & 0 deletions .changes/unreleased/FEATURES-20251014-173739.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: FEATURES
body: 'action/schema: Added `WriteOnly` schema field for action schemas.'
time: 2025-10-14T17:37:39.087475-04:00
custom:
Issue: "1233"
14 changes: 12 additions & 2 deletions action/schema/bool_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,16 @@ type BoolAttribute struct {
// xattr.TypeWithValidate interface, the validators defined in this field
// are run in addition to the validation defined by the type.
Validators []validator.Bool

// WriteOnly indicates that Terraform will not store this attribute value
// in the plan or state artifacts.
// If WriteOnly is true, either Optional or Required must also be true.
// WriteOnly cannot be set with Computed.
//
// This functionality is only supported in Terraform 1.11 and later.
// Practitioners that choose a value for this attribute with older
// versions of Terraform will receive an error.
WriteOnly bool
}

// ApplyTerraform5AttributePathStep always returns an error as it is not
Expand Down Expand Up @@ -166,9 +176,9 @@ func (a BoolAttribute) IsSensitive() bool {
return false
}

// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
// IsWriteOnly returns the WriteOnly field value.
func (a BoolAttribute) IsWriteOnly() bool {
return false
return a.WriteOnly
}

// IsRequiredForImport returns false as this behavior is only relevant
Expand Down
6 changes: 6 additions & 0 deletions action/schema/bool_attribute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,12 @@ func TestBoolAttributeIsWriteOnly(t *testing.T) {
attribute: schema.BoolAttribute{},
expected: false,
},
"writeOnly": {
attribute: schema.BoolAttribute{
WriteOnly: true,
},
expected: true,
},
}

for name, testCase := range testCases {
Expand Down
14 changes: 12 additions & 2 deletions action/schema/dynamic_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ type DynamicAttribute struct {
// xattr.TypeWithValidate interface, the validators defined in this field
// are run in addition to the validation defined by the type.
Validators []validator.Dynamic

// WriteOnly indicates that Terraform will not store this attribute value
// in the plan or state artifacts.
// If WriteOnly is true, either Optional or Required must also be true.
// WriteOnly cannot be set with Computed.
//
// This functionality is only supported in Terraform 1.11 and later.
// Practitioners that choose a value for this attribute with older
// versions of Terraform will receive an error.
WriteOnly bool
}

// ApplyTerraform5AttributePathStep always returns an error as it is not
Expand Down Expand Up @@ -167,9 +177,9 @@ func (a DynamicAttribute) IsSensitive() bool {
return false
}

// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
// IsWriteOnly returns the WriteOnly field value.
func (a DynamicAttribute) IsWriteOnly() bool {
return false
return a.WriteOnly
}

// IsRequiredForImport returns false as this behavior is only relevant
Expand Down
9 changes: 8 additions & 1 deletion action/schema/dynamic_attribute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-go/tftypes"

"github.com/hashicorp/terraform-plugin-framework/action/schema"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema"
"github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)

func TestDynamicAttributeApplyTerraform5AttributePathStep(t *testing.T) {
Expand Down Expand Up @@ -369,6 +370,12 @@ func TestDynamicAttributeIsWriteOnly(t *testing.T) {
attribute: schema.DynamicAttribute{},
expected: false,
},
"writeOnly": {
attribute: schema.DynamicAttribute{
WriteOnly: true,
},
expected: true,
},
}

for name, testCase := range testCases {
Expand Down
14 changes: 12 additions & 2 deletions action/schema/float32_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ type Float32Attribute struct {
// xattr.TypeWithValidate interface, the validators defined in this field
// are run in addition to the validation defined by the type.
Validators []validator.Float32

// WriteOnly indicates that Terraform will not store this attribute value
// in the plan or state artifacts.
// If WriteOnly is true, either Optional or Required must also be true.
// WriteOnly cannot be set with Computed.
//
// This functionality is only supported in Terraform 1.11 and later.
// Practitioners that choose a value for this attribute with older
// versions of Terraform will receive an error.
WriteOnly bool
}

// ApplyTerraform5AttributePathStep always returns an error as it is not
Expand Down Expand Up @@ -169,9 +179,9 @@ func (a Float32Attribute) IsSensitive() bool {
return false
}

// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
// IsWriteOnly returns the WriteOnly field value.
func (a Float32Attribute) IsWriteOnly() bool {
return false
return a.WriteOnly
}

// IsRequiredForImport returns false as this behavior is only relevant
Expand Down
6 changes: 6 additions & 0 deletions action/schema/float32_attribute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,12 @@ func TestFloat32AttributeIsWriteOnly(t *testing.T) {
attribute: schema.Float32Attribute{},
expected: false,
},
"writeOnly": {
attribute: schema.Float32Attribute{
WriteOnly: true,
},
expected: true,
},
}

for name, testCase := range testCases {
Expand Down
14 changes: 12 additions & 2 deletions action/schema/float64_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ type Float64Attribute struct {
// xattr.TypeWithValidate interface, the validators defined in this field
// are run in addition to the validation defined by the type.
Validators []validator.Float64

// WriteOnly indicates that Terraform will not store this attribute value
// in the plan or state artifacts.
// If WriteOnly is true, either Optional or Required must also be true.
// WriteOnly cannot be set with Computed.
//
// This functionality is only supported in Terraform 1.11 and later.
// Practitioners that choose a value for this attribute with older
// versions of Terraform will receive an error.
WriteOnly bool
}

// ApplyTerraform5AttributePathStep always returns an error as it is not
Expand Down Expand Up @@ -169,9 +179,9 @@ func (a Float64Attribute) IsSensitive() bool {
return false
}

// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
// IsWriteOnly returns the WriteOnly field value.
func (a Float64Attribute) IsWriteOnly() bool {
return false
return a.WriteOnly
}

// IsRequiredForImport returns false as this behavior is only relevant
Expand Down
8 changes: 7 additions & 1 deletion action/schema/float64_attribute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ func TestFloat64AttributeIsSensitive(t *testing.T) {
}
}

func TestFloat54AttributeIsWriteOnly(t *testing.T) {
func TestFloat64AttributeIsWriteOnly(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
Expand All @@ -370,6 +370,12 @@ func TestFloat54AttributeIsWriteOnly(t *testing.T) {
attribute: schema.Float64Attribute{},
expected: false,
},
"writeOnly": {
attribute: schema.Float64Attribute{
WriteOnly: true,
},
expected: true,
},
}

for name, testCase := range testCases {
Expand Down
14 changes: 12 additions & 2 deletions action/schema/int32_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ type Int32Attribute struct {
// xattr.TypeWithValidate interface, the validators defined in this field
// are run in addition to the validation defined by the type.
Validators []validator.Int32

// WriteOnly indicates that Terraform will not store this attribute value
// in the plan or state artifacts.
// If WriteOnly is true, either Optional or Required must also be true.
// WriteOnly cannot be set with Computed.
//
// This functionality is only supported in Terraform 1.11 and later.
// Practitioners that choose a value for this attribute with older
// versions of Terraform will receive an error.
WriteOnly bool
}

// ApplyTerraform5AttributePathStep always returns an error as it is not
Expand Down Expand Up @@ -169,9 +179,9 @@ func (a Int32Attribute) IsSensitive() bool {
return false
}

// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
// IsWriteOnly returns the WriteOnly field value.
func (a Int32Attribute) IsWriteOnly() bool {
return false
return a.WriteOnly
}

// IsRequiredForImport returns false as this behavior is only relevant
Expand Down
8 changes: 7 additions & 1 deletion action/schema/int32_attribute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ func TestInt32AttributeIsSensitive(t *testing.T) {
}
}

func TestInt2AttributeIsWriteOnly(t *testing.T) {
func TestInt32AttributeIsWriteOnly(t *testing.T) {
t.Parallel()

testCases := map[string]struct {
Expand All @@ -370,6 +370,12 @@ func TestInt2AttributeIsWriteOnly(t *testing.T) {
attribute: schema.Int32Attribute{},
expected: false,
},
"writeOnly": {
attribute: schema.Int32Attribute{
WriteOnly: true,
},
expected: true,
},
}

for name, testCase := range testCases {
Expand Down
14 changes: 12 additions & 2 deletions action/schema/int64_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ type Int64Attribute struct {
// xattr.TypeWithValidate interface, the validators defined in this field
// are run in addition to the validation defined by the type.
Validators []validator.Int64

// WriteOnly indicates that Terraform will not store this attribute value
// in the plan or state artifacts.
// If WriteOnly is true, either Optional or Required must also be true.
// WriteOnly cannot be set with Computed.
//
// This functionality is only supported in Terraform 1.11 and later.
// Practitioners that choose a value for this attribute with older
// versions of Terraform will receive an error.
WriteOnly bool
}

// ApplyTerraform5AttributePathStep always returns an error as it is not
Expand Down Expand Up @@ -169,9 +179,9 @@ func (a Int64Attribute) IsSensitive() bool {
return false
}

// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
// IsWriteOnly returns the WriteOnly field value.
func (a Int64Attribute) IsWriteOnly() bool {
return false
return a.WriteOnly
}

// IsRequiredForImport returns false as this behavior is only relevant
Expand Down
6 changes: 6 additions & 0 deletions action/schema/int64_attribute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,12 @@ func TestInt64AttributeIsWriteOnly(t *testing.T) {
attribute: schema.Int64Attribute{},
expected: false,
},
"writeOnly": {
attribute: schema.Int64Attribute{
WriteOnly: true,
},
expected: true,
},
}

for name, testCase := range testCases {
Expand Down
14 changes: 12 additions & 2 deletions action/schema/list_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ type ListAttribute struct {
// xattr.TypeWithValidate interface, the validators defined in this field
// are run in addition to the validation defined by the type.
Validators []validator.List

// WriteOnly indicates that Terraform will not store this attribute value
// in the plan or state artifacts.
// If WriteOnly is true, either Optional or Required must also be true.
// WriteOnly cannot be set with Computed.
//
// This functionality is only supported in Terraform 1.11 and later.
// Practitioners that choose a value for this attribute with older
// versions of Terraform will receive an error.
WriteOnly bool
}

// ApplyTerraform5AttributePathStep returns the result of stepping into a list
Expand Down Expand Up @@ -187,9 +197,9 @@ func (a ListAttribute) IsSensitive() bool {
return false
}

// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
// IsWriteOnly returns the WriteOnly field value.
func (a ListAttribute) IsWriteOnly() bool {
return false
return a.WriteOnly
}

// IsRequiredForImport returns false as this behavior is only relevant
Expand Down
7 changes: 6 additions & 1 deletion action/schema/list_attribute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,12 @@ func TestListAttributeIsWriteOnly(t *testing.T) {
attribute: schema.ListAttribute{},
expected: false,
},
"writeOnly": {
attribute: schema.ListAttribute{
WriteOnly: true,
},
expected: true,
},
}

for name, testCase := range testCases {
Expand All @@ -392,7 +398,6 @@ func TestListAttributeIsWriteOnly(t *testing.T) {
})
}
}

func TestListAttributeListValidators(t *testing.T) {
t.Parallel()

Expand Down
20 changes: 18 additions & 2 deletions action/schema/list_nested_attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,19 @@ type ListNestedAttribute struct {
// xattr.TypeWithValidate interface, the validators defined in this field
// are run in addition to the validation defined by the type.
Validators []validator.List

// WriteOnly indicates that Terraform will not store this attribute value
// in the plan or state artifacts.
// If WriteOnly is true, either Optional or Required must also be true.
// WriteOnly cannot be set with Computed.
//
// If WriteOnly is true for a nested attribute, all of its child attributes
// must also set WriteOnly to true and no child attribute can be Computed.
//
// This functionality is only supported in Terraform 1.11 and later.
// Practitioners that choose a value for this attribute with older
// versions of Terraform will receive an error.
WriteOnly bool
}

// ApplyTerraform5AttributePathStep returns the Attributes field value if step
Expand Down Expand Up @@ -215,9 +228,9 @@ func (a ListNestedAttribute) IsSensitive() bool {
return false
}

// IsWriteOnly always returns false as action schema attributes cannot be WriteOnly.
// IsWriteOnly returns the WriteOnly field value.
func (a ListNestedAttribute) IsWriteOnly() bool {
return false
return a.WriteOnly
}

// IsRequiredForImport returns false as this behavior is only relevant
Expand Down Expand Up @@ -245,4 +258,7 @@ func (a ListNestedAttribute) ValidateImplementation(ctx context.Context, req fws
if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) {
resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path))
}
if a.IsWriteOnly() && !fwschema.ContainsAllWriteOnlyChildAttributes(a) {
resp.Diagnostics.Append(fwschema.InvalidWriteOnlyNestedAttributeDiag(req.Path))
}
}
Loading