Accessing resource configuration attributes directly

Through our API we allow image digests to be optionally set by the user (Function — oci 2.32.0 documentation). In the case where a digest is sent in the request that digest is used and the state is updated accordingly. When no digest is sent with the request, our control plane will query the metadata of the image and use its latest digest and the state should be updated with that newly sourced digest. We have recently been informed of a bug in our provider plugin (GitHub - terraform-providers/terraform-provider-oci: Terraform Oracle Cloud Infrastructure provider) where image digests for function resources are not being updated and, through debugging, have found that once a digest has been computed it is retained for subsequent requests unless the image digest attribute has been set (even if the tag has changed). What we would like to see here is if the attribute isn’t set or is empty then the value is always computed.

Reading through similar issues and documentation I understand that a computed value is only computed at create time, unless there is some custom logic to enforce that an attribute should be computed based on some condition/s. Through debugging I was able to confirm that when the attribute wasn’t set it was picking up the computed value from the state. What would be good for us here is if there was some way to get the raw value from the resource configuration itself and determine if that attribute was set and include this in such a conditional. My first question, though not hopeful, is: is anything like this exposed through the SDK? If not, what’s the recommended practice here?

A workaround we have been looking at is to stop that attribute from being computed. Then, in our update method, we could exclude the image digest from the API request should that value be empty (or non-existent).

`if imageDigest, ok := s.D.GetOkExists("image_digest"); ok {
	tmp := imageDigest.(string)
	if tmp == "" {
		request.ImageDigest = nil
	} else {
		request.ImageDigest = &tmp
	}
}`

This “works” but will always show a -> nil change in the diff if that attribute isn’t set. We could suppress this buy using a custom suppress diff function which reaches out to the API to get the generated image digest and suppress if they are the same or, if not, display the new one in the diff but this will mean added work to our CP and we would like to see if there is a quick fix here.

So, what computed means is “if the user doesn’t specify a value, the provider gets to pick one”. I believe it’s the current SDK implementation and not an inherent part of Terraform that values in state get automatically substituted when there’s no user value to fall back on.

Currently, there’s not really any reliable way to detect when this happens, because the config/state aren’t really exposed to the provider developer, instead surfacing the ResourceData abstraction. I think hashicorp/terraform-plugin-sdk#133 is the issue tracking this.

terraform-plugin-go exposes both the configuration and state and so offers a workaround, but that’s a steep cost for the workaround.