Terraform destroys resources before updating dependent resources
Hi, suppose you have the folowing desired state:
resource "foo" "my_foo_1" {
name = "foo1"
}
resource "foo" "my_foo_2" {
name = "foo2"
}
resource "bar" "my_bar" {
foo = foo.my_foo_1.id
}
You do terraform apply and my_foo_1, my_foo_2 and my_bar are created.
Then you change your desired state to this:
# Removed my_foo_1
resource "foo" "my_foo_2" {
name = "foo2"
}
resource "bar" "my_bar" {
foo = foo.my_foo_2.id # Reference changed
}
If you do terraform apply now, Terraform should:
- Update
my_bar, pointing tomy_foo_2instead ofmy_foo_1(note: assume this is an in-place update and not a replacement) - Delete
my_foo_1
But the order if these actions is crucial: the update has to be done before the delete, otherwise the backend API will complain that my_foo_1 is referenced by some other resource (i.e. my_bar) so it cannot be deleted.
What happens, though, is that Terraform starts by destroying my_foo_1 and obviously fails.
When I noticed this behavior I was really surprised, because my_bar is clearly dependent on my_foo_1, so I don’t understand why Terraform destroys my_foo_1 before updating my_bar.
My best guess is that there are situations where this behavior makes sense.
But I think that the scenario I’m describing is pretty common and reasonable. After all, it’s just moving from a valid desired state to another perfectly valid desired state.
Of course I could solve the issue by introducing an intermediate state where my_foo_1 is still present but my_bar doesn’t reference it anymore:
resource "foo" "my_foo_1" {
name = "foo1"
}
resource "foo" "my_foo_2" {
name = "foo2"
}
resource "bar" "my_bar" {
foo = foo.my_foo_2.id # Reference changed
}
But this it’s just a workaround and it kinda breaks the declarative paradigm by forcing me to tell Terraform how to order the updates to my infrastructure.
Is there a way to make Terraform behave properly that doesn’t involve breaking the transition in two steps / two terraform apply executions?
Assume that I’m the developer of the provider defining foo and bar resources, so I accept solutions that involve modifying the provider.