Possible to 'ignore_changes' but still manage?

Searching for ideas here. Thank you in advance for help!

When you direct Terraform to ‘ignore_changes’ of an attribute of a resource using the lifecycle block, Terraform both ignores changes of this attribute when determining if the resource needs changing, AND also never touches this attribute if the resource ever changes for any other reason. Can anyone think of a way to get Terraform to ignore changes of an attribute when determining if a resource needs changing, but Terraform would still make updates to that attribute if the resource gets updated for any other reason? Basically, “don’t allow this attribute to trigger a change, but still manage it for me”.

Thanks again,
Chris

Hi @outdoors_007,

I think I’m not fully understanding the distinction you are making between the two behaviors you are describing; from my perspective they both sound like the same behavior described in different words.

Since I don’t think I understand your question yet, I’m going to try to explain a little about how ignore_changes works and then maybe that will help to describe the effect you want in these terms and then we can see if what you want to achieve is already possible, or if you are describing something Terraform doesn’t support yet.

The first thing to note is that when you aren’t using ignore_changes the normal flow is for Terraform to send to the provider both the configuration and the prior state, and then it’s the provider’s job to compare the two and decide what would need to change in order for the new state to match the configuration. If a provider returns a value that is different than the prior state, Terraform will present that either as an update action or a replace action, depending on whether the provider indicated that it is able to make the change as an in-place update.

When adding ignore_changes this behavior is slightly modified so that Terraform will essentially ignore what’s written in the configuration and just take the value in the state as the new value, regardless of what you wrote in the configuration. This means that e.g. you can safely change an argument that would normally require the object to be recreated, but not actually recreate the object until it would’ve been recreated for some other reason, or until you add a new instance of the resource that would be created from the configuration as currently written.

When I think about Terraform “managing an attribute” what that means to me is the process I described above where Terraform asks the provider to decide how to change the prior state to match the configuration. If Terraform isn’t proposing actions to make the remote system match the configuration then by this definition it would not be “managing the state”; “don’t allow triggering a change” and “manage this” are mutually exclusive.

With that said, I expect you have some different meanings in mind when you use those terms and so I’d like to understand more about what behavior you’d like to see, so I can think about how to describe it in Terraform’s terms. Does the above description give you some extra concepts to frame your question with?

Thanks!

Hi. Thank you for the quick response and explanation. I think you get the gist of my question. I guess I’m just trying to take a behavior and split it into two separate steps: detect a change and implement a change. Could Terraform ignore a change to a specific attribute of a resource when trying to determine if it needs updating, but still update that attribute if the resource changed for any other reason(any other attribute changes). According to your reply, the answer is no. Thank you for confirming.

Here’s what I’m actually trying to accomplish so if you have any ideas, please let me know:

For any resource that changes in our production environment during a ‘terraform apply’, I’d like a particular ‘change_request’ tag updated with a new value. Every resource that accepts tags has this tag(we specify it as a default tag in the aws provider block), but only the resources that changed(or were added) will receive the new value for this tag. It’s basically a way for us to add traceability of changes to our resources. When we see a resource in AWS, we can check this tag value and know the ‘change_request’ that last changed this resource.

Again, thanks for your guidance. Much appreciated.

Thanks for the further explanation, @outdoors_007. I understand that what you want is a way to specify that a particular argument should not be updated to reflect new configuration except if another argument on the same resource also needs updating and the two can be updated together.

That is indeed not available: if you specify ignore_changes then Terraform will always disregard the configuration changes for the specified arguments, even if other arguments have changed.

The only time Terraform will incorporate a new value for an argument that has ignore_changes set is when entirely replacing the object – deleting the old one and creating a new one – in which case the new object will adopt the value as currently specified in the configuration.


Unfortunately I don’t have an alternative answer to suggest to meet the need you described. I understand that you’d like to put some information in the remote system so you can trace objects back to the code or code change that created or most recently updated them; Terraform typically tracks that relationship only in the opposite direction, from Terraform’s own state snapshots to the remote objects.

With ignore_changes as it exists today you could potentially track the change request that originally created the object, but that would not track any in-place updates.