BunnyWay / terraform-provider-bunnynet

bunny.net Terraform provider
https://registry.terraform.io/providers/BunnyWay/bunnynet
Mozilla Public License 2.0
7 stars 1 forks source link

[bug] Deleting Storage Fails Pull Zone Deletion #14

Open lorenzoaiello opened 1 month ago

lorenzoaiello commented 1 month ago

If I have a Storage Zone and a Pull Zone defined in Terraform, renaming the Storage Zone causes a recreation operation. This creates a bit of a race condition when Terraform tries to delete a pull zone that has already been deleted automatically when the storage zone is deleted.

This function should be updated to succeed if a 404 is returned gracefully. https://github.com/BunnyWay/terraform-provider-bunnynet/blob/522190fd6251d5d84fe03f83f3404a33933190ae/internal/api/pullzone.go#L242

Example TF output:

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  ~ update in-place
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # module.icing.bunnynet_pullzone.this will be updated in-place
  ~ resource "bunnynet_pullzone" "this" {
        id                                    = **redacted**
        name                                  = "**redacted**"
        # (84 unchanged attributes hidden)

      ~ origin {
          ~ storagezone         = **redacted** -> (known after apply)
            # (5 unchanged attributes hidden)
        }

        # (1 unchanged block hidden)
    }

  # module.icing.bunnynet_storage_zone.this must be replaced
-/+ resource "bunnynet_storage_zone" "this" {
      ~ date_modified       = "24-09-17T18:55:08" -> (known after apply)
      ~ hostname            = "storage.bunnycdn.com" -> (known after apply)
      ~ id                  = **redacted** -> (known after apply)
      ~ name                = "**redacted**" -> "**redacted**" # forces replacement
      ~ password            = (sensitive value)
      ~ password_readonly   = (sensitive value)
        # (4 unchanged attributes hidden)
    }

Plan: 1 to add, 1 to change, 1 to destroy.
module.cdn.bunnynet_storage_zone.this: Destroying... [name=**redacted**]
module.cdn.bunnynet_storage_zone.this: Destruction complete after 1s
module.cdn.bunnynet_storage_zone.this: Creating...
module.cdn.bunnynet_storage_zone.this: Creation complete after 0s [name=**redacted**]
module.cdn.bunnynet_pullzone.this: Modifying... [name=**redacted**]
╷
│ Error: Error updating pullzone
│ 
│   with module.cdn.bunnynet_pullzone.this,
│   on modules/cdn/pullzone.tf line 1, in resource "bunnynet_pullzone" "this":
│    1: resource "bunnynet_pullzone" "this" {
│ 
│ The requested Pull Zone was not found
╵
rafael-at-bunny commented 1 month ago

Hi!

The issue is not necessarely on DeletePullzone, but rather on UpdatePullzone, as terraform is trying to change the storage zone associated in the pullzone, but the pullzone has already been deleted.

That happens because internally, when you delete the storage zone, the associated pullzone would have no origin anymore, so the historical behavior for the Bunny API is to delete the associated pullzone as well. If you'd like to rename the Storage Zone manually via dash.bunny.net, you'd have to create the new storage zone first, change the pullzone's origin, and then delete the old storage zone. Terraform does not offer a way to explicitly control the order of operations, and it also doesn't like when resources shift/disappear under its feet, hence the error.

Terraform only allows me to control its plan, so I could make it reflect what would happen in the API, by forcing the pullzone to be replaced when it's storage zone is changed. While this would fix your issue, re-creating the pullzone has one side-effect that its statistics will be gone, and you'd need two passes to remedy. In situations that you're explicitly changing the pullzone's origin from one storage zone to another (without deleting the original), it would also cause a replace, and there would be no workaround that doesn't involve multiple passes.

So I'm not exactly sure what to do. Either of "renaming the storage zone" or "changing the pullzone's origin storage" would have to happen in multiple passes, and I'm not sure which case is more common. For your particular case, the workaround would be:

  1. Declare the new storage zone resource;
  2. Change the pullzone's origin;
  3. terraform apply;
  4. Remove the old storage zone resource;
  5. terraform apply

I'm open to suggestions on how to handle that gracefully, hopefully without multiple passes.

Thank you.