terraform

Delete a Terraform resource only if a "parent" resource is not removed


I am developing a Terraform provider using the old SDKv2. I have 2 resources, let's say note and version.

// main.tf
resource note n1 { }

resource version v1 {
  note = n1.id
}

If I remove both resources at once and apply, I want Terraform to call only Delete on note, and not on version. (The server will handle version deletion).

// main.tf
// removed both resources at once
// only note Delete is called

However, if I remove v1 and apply, I want (as usual) Terraform to call Delete on version.

// main.tf
resource resource note n1 { }
// version Delete is called

Is it possible, or I am asking for something very against Terraform principles?

We want to do it, because there's a current version, and the server doesn't allow to delete the current version of a note (but you can delete the note altogether).

(It is OK if the last example fails, i.e. deleting v1, since that's the current version of the note. The user should add another version first, or delete both resources.)


Solution

  • From the perspective of a Terraform provider plugin, each resource instance is independent of all others. There is no way for a provider to cause Terraform Core to treat one resource differently because of the plan that has been generated for another.

    I'm not sure what else to suggest with the information provided, but in general it doesn't work very well to represent "the current version of X" as a Terraform resource type, because Terraform is designed for managing long-lived objects by updating them in-place rather than by appending new versions of them.


    For some API designs it can be appropriate to hide the explicit concept of versions altogether and to instead make the resource type for the versioned object type ("note", in your case) behave as if the object is mutable but then implement "update in-place" by quietly creating a new version. This makes the versioning scheme an implementation detail, rather than an explicit part of the provider API: authors would represent their intention to create a new version of a note by changing the note's configuration, and then the provider would implement that by creating a new version that matches the changed configuration.

    For example, what I described matches the design of aws_s3_object in the hashicorp/aws provider when used with an S3 bucket that has object versioning enabled. Each time the author changes the resource configuration to specify a different object body, the provider presents that as an in-place update to the resource instance but once applied a new version of the object is implicitly created, and the version_id attribute changes to reflect that.