As far as I can tell, all delete operations are always executed as the very last thing to happen, ev...
t
As far as I can tell, all delete operations are always executed as the very last thing to happen, even in a context where the delete of a sub resources within a component is an 'update to the component itself. In that case, the component's
after_update
hook executes before the delete lifecycle method.
s
We usually create before we delete (this behavior can be changed via ResourceOptions), but deletes are not the last thing to happen in the entire graph of operations if that's what you meant. Can you explain more about the structure of your Pulumi program?
t
There are cases where delete before create makes sense, but not where the resource is intended to be permanently deleted, which is ours. In this case, downstream dependencies that will wait, either due to depends_on or which have some input dependency on an upstream output, do not do so in the delete case. Presumably this is because a deleted resource no longer exists and so does not constrain the graph transitions. Take for example this case:
Copy code
network_devices = {}
for network_device in device_list:
    ndev = NetDevice(
        name=f"{name}-{network_device.name}",
        args=NetDeviceInputs(
            spec=network_device,
            vm_uuid=virdomain.id,
        ),
        opts=pulumi.ResourceOptions(
            parent=self,
            depends_on=[
                *network_devices.values(),
            ]
        ),
    )
    network_devices[network_device.name] = ndev

boot_order = BootOrder(
    name=f"{name}-boot-order",
    args=BootOrderInputs(boot_devices=boot_devs),
    opts=pulumi.ResourceOptions(
        parent=self,
        depends_on=[
            *network_devices.values(),
        ],
    ),
)
If a network device is deleted, it's
delete
method invocation, which may have operations that need to resolve prior to the execution of the BootOrder methods, and which do wait in any case apart from delete, do not cause BootOrder to wait in the delete case. This makes sense because the dependency no longer exists in the program, but that's a problem if deletion of a net device requires an operation that BootOrder must wait for.
This is was caused us to introduce in these scenarios something like a NetDeviceController, which takes as input a list of net device UUIDs and handled deletion in the controller update method, which, if BootOrder depends on the controller, will cause it to wait. It just seems like this is a hack to get around something that there should be (and may be -- I just don't know) an option for in Pulumi.
@stocky-restaurant-98004 ^
s
Hmm. I don't think I'm really following. Can you maybe rephrase your question in a simpler way or use a simpler example? I don't know what you mean by "delete method invocation" or "operations that need to resolve". Or maybe it would be helpful to explain what operations you're referring to. Do you mean that your resource can't be deleted immediately and has to shut down gracefully in a particular way?
e
It just seems like this is a hack to get around something that there should be (and may be -- I just don't know) an option for in Pulumi.
The trickiness here is the engine knowing when to delete something. Like in the example here the state currently will have a NetDevice and a BootOrder depending on that NetDevice. If on the next program run we see the BootOrder that might mean the NetDevice is deleted, but it might just mean the NetDevice is being used by some other different resource later. The only time we can know that the NetDevice is gone and can be deleted is at the end of the program when no more resource registrations can happen. At that point we can look and go, "ok we haven't seen a registration for this NetDevice so it must need deleting". The only thing that comes to mind here is some option for the user to tell the engine "hey if I get registered and some of my old dependencies haven't been registered yet I promise I've removed them from the program and you can delete them after processing my update". Note that it would have to be done after the resources update because otherwise it's likely the cloud console will block the deletes because the current state still refers to the old dependencies. We'd also want to work out what the right way to wait for those deletes is, it's not clear that by default all those deletes should block the resolution of the resource being updated.