Skip to content

Write-only dynamic attribute causes plan diff everytime #1096

@magodo

Description

@magodo

Module version

ecd80f67daed

Relevant provider source code

...

Terraform Configuration Files

terraform {
  required_providers {
    restful = {
      source = "magodo/restful"
    }
  }
}

provider "restful" {
  base_url = "http://local:3000"
}

variable "foo" {
   type = string
   ephemeral = true
   default = null
}

resource "restful_resource" "test" {
  path = "/resources"
  read_path = "/resources/$(body.id)"
  body = {
      foo = "bar"
  }
  ephemeral_body = {
    bar = var.foo
  }
}

Debug Output

After the initial successful apply, any further plan will cause diff:

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # restful_resource.test will be updated in-place
  ~ resource "restful_resource" "test" {
        id             = "/resources/2"
      ~ output         = {
          - foo = "bar"
          - id  = 2
        } -> (known after apply)
        # (4 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Expected Behavior

If I understand the document correctly:

Write-only argument values cannot produce a Terraform plan difference.

This is because the prior state value for a write-only argument will always be null and the planned/final state value will also be null, therefore, it cannot produce a diff on its own.

Even if the ephemeral input variable got changed, the plan shall also show no diff as long as other non write-only attributes are not changed.

Actual Behavior

After the initial successful apply, any further plan will cause diff.

Steps to Reproduce

Use the branch https://github.com/magodo/terraform-provider-restful/tree/ephemeral_body to build and use the provider locally.

References

Note that the output attribute is Dynamic type. I've also tried to generate the plan output, which is like below:

{
  "format_version": "1.2",
  "terraform_version": "1.12.0-dev",
  "variables": {
    "foo": {
      "value": null
    }
  },
  "planned_values": {
    "root_module": {
      "resources": [
        {
          "address": "restful_resource.test",
          "mode": "managed",
          "type": "restful_resource",
          "name": "test",
          "provider_name": "registry.terraform.io/magodo/restful",
          "schema_version": 2,
          "values": {
            "body": {
              "foo": "bar"
            },
            "check_existance": null,
            "create_header": null,
            "create_method": null,
            "create_query": null,
            "create_selector": null,
            "delete_body": null,
            "delete_header": null,
            "delete_method": null,
            "delete_path": null,
            "delete_query": null,
            "ephemeral_body": null,
            "force_new_attrs": null,
            "header": null,
            "id": "/resources/1",
            "merge_patch_disabled": null,
            "output_attrs": null,
            "path": "/resources",
            "poll_create": null,
            "poll_delete": null,
            "poll_update": null,
            "precheck_create": null,
            "precheck_delete": null,
            "precheck_update": null,
            "query": null,
            "read_header": null,
            "read_path": "/resources/$(body.id)",
            "read_query": null,
            "read_response_template": null,
            "read_selector": null,
            "update_body_patches": null,
            "update_header": null,
            "update_method": null,
            "update_path": null,
            "update_query": null,
            "write_only_attrs": null
          },
          "sensitive_values": {
            "body": {}
          }
        }
      ]
    }
  },
  "resource_changes": [
    {
      "address": "restful_resource.test",
      "mode": "managed",
      "type": "restful_resource",
      "name": "test",
      "provider_name": "registry.terraform.io/magodo/restful",
      "change": {
        "actions": [
          "update"
        ],
        "before": {
          "body": {
            "foo": "bar"
          },
          "check_existance": null,
          "create_header": null,
          "create_method": null,
          "create_query": null,
          "create_selector": null,
          "delete_body": null,
          "delete_header": null,
          "delete_method": null,
          "delete_path": null,
          "delete_query": null,
          "ephemeral_body": null,
          "force_new_attrs": null,
          "header": null,
          "id": "/resources/1",
          "merge_patch_disabled": null,
          "output": {
            "bar": "baz",
            "foo": "bar",
            "id": 1
          },
          "output_attrs": null,
          "path": "/resources",
          "poll_create": null,
          "poll_delete": null,
          "poll_update": null,
          "precheck_create": null,
          "precheck_delete": null,
          "precheck_update": null,
          "query": null,
          "read_header": null,
          "read_path": "/resources/$(body.id)",
          "read_query": null,
          "read_response_template": null,
          "read_selector": null,
          "update_body_patches": null,
          "update_header": null,
          "update_method": null,
          "update_path": null,
          "update_query": null,
          "write_only_attrs": null
        },
        "after": {
          "body": {
            "foo": "bar"
          },
          "check_existance": null,
          "create_header": null,
          "create_method": null,
          "create_query": null,
          "create_selector": null,
          "delete_body": null,
          "delete_header": null,
          "delete_method": null,
          "delete_path": null,
          "delete_query": null,
          "ephemeral_body": null,
          "force_new_attrs": null,
          "header": null,
          "id": "/resources/1",
          "merge_patch_disabled": null,
          "output_attrs": null,
          "path": "/resources",
          "poll_create": null,
          "poll_delete": null,
          "poll_update": null,
          "precheck_create": null,
          "precheck_delete": null,
          "precheck_update": null,
          "query": null,
          "read_header": null,
          "read_path": "/resources/$(body.id)",
          "read_query": null,
          "read_response_template": null,
          "read_selector": null,
          "update_body_patches": null,
          "update_header": null,
          "update_method": null,
          "update_path": null,
          "update_query": null,
          "write_only_attrs": null
        },
        "after_unknown": {
          "body": {},
          "output": true
        },
        "before_sensitive": {
          "body": {},
          "output": {}
        },
        "after_sensitive": {
          "body": {}
        }
      }
    }
  ],
  "prior_state": {
    "format_version": "1.0",
    "terraform_version": "1.12.0",
    "values": {
      "root_module": {
        "resources": [
          {
            "address": "restful_resource.test",
            "mode": "managed",
            "type": "restful_resource",
            "name": "test",
            "provider_name": "registry.terraform.io/magodo/restful",
            "schema_version": 2,
            "values": {
              "body": {
                "foo": "bar"
              },
              "check_existance": null,
              "create_header": null,
              "create_method": null,
              "create_query": null,
              "create_selector": null,
              "delete_body": null,
              "delete_header": null,
              "delete_method": null,
              "delete_path": null,
              "delete_query": null,
              "ephemeral_body": null,
              "force_new_attrs": null,
              "header": null,
              "id": "/resources/1",
              "merge_patch_disabled": null,
              "output": {
                "bar": "baz",
                "foo": "bar",
                "id": 1
              },
              "output_attrs": null,
              "path": "/resources",
              "poll_create": null,
              "poll_delete": null,
              "poll_update": null,
              "precheck_create": null,
              "precheck_delete": null,
              "precheck_update": null,
              "query": null,
              "read_header": null,
              "read_path": "/resources/$(body.id)",
              "read_query": null,
              "read_response_template": null,
              "read_selector": null,
              "update_body_patches": null,
              "update_header": null,
              "update_method": null,
              "update_path": null,
              "update_query": null,
              "write_only_attrs": null
            },
            "sensitive_values": {
              "body": {},
              "output": {}
            }
          }
        ]
      }
    }
  },
  "configuration": {
    "provider_config": {
      "restful": {
        "name": "restful",
        "full_name": "registry.terraform.io/magodo/restful",
        "expressions": {
          "base_url": {
            "constant_value": "http://local:3000"
          }
        }
      }
    },
    "root_module": {
      "resources": [
        {
          "address": "restful_resource.test",
          "mode": "managed",
          "type": "restful_resource",
          "name": "test",
          "provider_config_key": "restful",
          "expressions": {
            "body": {
              "constant_value": {
                "foo": "bar"
              }
            },
            "ephemeral_body": {
              "references": [
                "var.foo"
              ]
            },
            "path": {
              "constant_value": "/resources"
            },
            "read_path": {
              "constant_value": "/resources/$(body.id)"
            }
          },
          "schema_version": 2
        }
      ],
      "variables": {
        "foo": {
          "default": null
        }
      }
    }
  },
  "timestamp": "2025-02-19T01:28:46Z",
  "applyable": true,
  "complete": true,
  "errored": false
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions