Sorry, yeah, this is all confusing. The behavior with an unset field not showing up in GetChange sounds like an optimization somewhere to me–no change was detected, so it isn’t populating the values. That’s the way the method was intended to be used, to detect what the change was when you know there was a change, which is why it’s (unfortunately) not a bulletproof way to detect this kind of information.
The null and empty string stuff is a symptom of the current SDK (which has no concept of null) being layered over the Terraform 0.12 type system (which has the concept of null). This is why
GetOk is unreliable; it’s just checking that the value isn’t the empty string, not for null .
GetOkExists is sometimes more accurate, but is also leaky and will sometimes not recognize the difference between empty values and unset. Currently, there’s no sure way to do that. That’s something we’re working on, still.