terraform-plugin-framework icon indicating copy to clipboard operation
terraform-plugin-framework copied to clipboard

Computed sensitive attribute alongside computed boolean in SetNestedAttribute causes entire set to be deleted and recreated in subsequent plans

Open henryrecker-pingidentity opened this issue 5 months ago • 1 comments

Module version

github.com/hashicorp/terraform-plugin-framework v1.11.0

Relevant provider source code

func (r *sensitiveResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
	resp.Schema = schema.Schema{
		Description: "Sensitive resource.",
		Attributes: map[string]schema.Attribute{
			"tables": schema.SetNestedAttribute{
				Description: "List of configuration tables.",
				Optional:    true,
				NestedObject: schema.NestedAttributeObject{
					Attributes: map[string]schema.Attribute{
						"rows": schema.ListNestedAttribute{
							Description: "List of table rows.",
							Optional:    true,
							NestedObject: schema.NestedAttributeObject{
								Attributes: map[string]schema.Attribute{
									"sensitive_fields": schema.SetNestedAttribute{
										Description: "The sensitive configuration fields in the row.",
										Optional:    true,
										Computed:    true,
										Default: setdefault.StaticValue(types.SetValueMust(types.ObjectType{AttrTypes: map[string]attr.Type{
											"name":  types.StringType,
											"value": types.StringType,
										}}, nil)),
										NestedObject: schema.NestedAttributeObject{
											Attributes: map[string]schema.Attribute{
												"name": schema.StringAttribute{
													Description: "The name of the configuration field.",
													Required:    true,
												},
												"value": schema.StringAttribute{
													Description: "The sensitive value for the configuration field.",
													Required:    true,
													Sensitive:   true,
												},
											},
										},
									},
									"default_row": schema.BoolAttribute{
										Description: "Whether this row is the default.",
										Computed:    true,
										Optional:    true,
										Default:     booldefault.StaticBool(false),
									},
								},
							},
						},
					},
				},
			},
		},
	}
}

func (r *sensitiveResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
	resp.State.Raw = req.Plan.Raw
}

func (r *sensitiveResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
	resp.State.Raw = req.State.Raw
}

func (r *sensitiveResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
	resp.State.Raw = req.Plan.Raw
}

func (r *sensitiveResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
}

Terraform Configuration Files

resource "example_sensitive" "sensitive" {
  # If tables is a list instead of a set, the unexpected plans do not occur
  tables = [
    {
      rows = [
        {
          fields = [
            {
              name  = "Key ID"
              value = "jwtSymmetricKey1"
            },
            {
              name  = "Encoding"
              value = "b64u"
            }
          ]
          sensitive_fields = [
            {
              name  = "Key"
              value = "Asdf"
            },
          ]
          # If this attribute is uncommented, the unexpected plans do not occur
          # default_row = false
        }
      ]
    },
  ]
}

Debug Output

https://gist.github.com/henryrecker-pingidentity/9cb39885e2d338fc7189543d501b413c

Expected Behavior

Plans after initial create should indicate no changes needed, infrastructure matches configuration.

Actual Behavior

After a Create runs successfully, a subsequent apply will generate a plan that completely deletes the "tables" attribute. Another subsequent apply after that will recreate the "tables" attribute, as it is written in the HCL. And it will continue to flip-flop from there.

If the "tables" attribute is changed to ListNestedAttribute rather than SetNestedAttribute, the bug stops occurring.

Steps to Reproduce

Apply provided HCL repeatedly. Uncommenting the "default_row" boolean prevents the flip-flopping, as does changing tables to a list in the schema.

This provider can be found on the "SensitivePlanBug" branch here - https://github.com/henryrecker-pingidentity/terraform-provider-example/tree/SensitivePlanBug

References

Seems very similar to #867