Possibility of overriding state value on plan/apply

So I am trying to use terraform to manage TeamCity build configurations using the bestseller-ecom/teamcity provider (I’m aware this is very out of date, but there’s better afaik)

Everything works perfectly except that I keep getting a repeated configuration change for the same property because the TeamCity API is accepting a “secure” parameter(in this case an access token) but this parameter gets returned as blank and thus saved to state as blank. So the next time I plan/apply terraform attempts to set the parameter back to the value it’s supposed to be (even though it already is), because the state see’s it as blank

What I’m wondering is, is there some preprocessing or something I can do on the state file to override this blank value before my terraform file is applied?

I’m still new to using terraform so if I’m completely off the mark just let me know, I’m open to doing this in whatever the “best” way possible is, overriding state file is only thing I can come up with myself though…

Hi @katakuna,

This sounds like a bug in the provider itself, it should never try to override a value which is in the configuration. You may find some warnings in the logs about invalid values we must accept because the provider “is using the legacy plugin SDK”. If the change is only happening during the next refresh, it’s not something we can catch in Terraform, but it is not expected behavior from the provider.

In the meantime, if the value is not required by the provider after the first apply, you may be able to use ignore_changes to indicate that Terraform should not attempt to revert changes on that field made by the configuration.

1 Like

I agree that it is likely a bug within the provider, but I do believe that the TeamCity api just refusing to return that value so you can’t even tell that it was “set” in the first place.

On the upside though, ignore_changes does exactly what I ned for this! I can set the secure value on initial create and then just ignore it going forwards so thank you @jbarbin!

In case you’d like to report it upstream to the provider developers, the expected way to handle an attribute that is “write-only” in an upstream API is for the provider’s “read” function to retain the value from the prior state, optimistically assuming that the value hasn’t changed upstream.

The behavior you’ve observed so far – it setting the attribute to an empty string – tells Terraform Core that the value has changed upstream to be an empty string. If the provider doesn’t know that the value has changed, it should assume it hasn’t and leave the prior value in the state so that Terraform can still compare it with the configuration and notice whether the configuration has changed since what was originally configured.

ignore_changes can work around it, but it is tricky because that feature is intended for telling Terraform to ignore changes in the configuration, rather than changes in the remote system. When a provider misbehaves like this Terraform can’t actually tell whether it was the configuration or the remote system that changed – there is no record of what the configuration used to look like – and so Terraform believes that the previous configuration had that argument set to the empty string and that you’ve now changed it to be non-empty, which is of course the opposite of what’s actually happened.

This “white lie” to Terraform isn’t a big deal for the purposes of allowing your configuration to eventually converge on a stable state, but you may sometimes notice some other side-effects, such as Terraform reporting that this value has “changed outside of Terraform” if Terraform Core determines that the change might’ve caused a change elsewhere in the plan. Because of that, I would recommend discussing this problem with the provider developers just to avoid potential future confusion, with Terraform giving misleading feedback to the operator as a result of the provider giving misleading feedback to Terraform.