In this post, I will try to test experimentally and understand the order in which CloudFormation resources are created, updated and deleted. I will explore 3 different approaches, with and without CloudFormation resource dependencies, and finally nested stacks with dependencies.
These are the 3 scenarios:
Without dependencies between CloudFormation resources,
with dependencies between CloudFormation resources using the
DependsOnattribute (or the equivalent syntax in CDK), and finally
by placing resources in nested stacks and enforcing dependencies at the nested stack level.
The complete code used in this experiment can be found in this AWS CDK project on github.
I am using CloudFormation custom resources that allow me to run custom code and record the exact time a resource was created/updated/deleted. I record this information in an Amazon Timestream database.
The project contains a core stack, that defines the Timestream database and the custom resource provider. The lambda function of the custom resource provider handles the create/update/delete events for the custom resources and records the following information in the database
Time of event
The name of the resource
The version of the resource (this is an attribute that I change to trigger an update)
The type of the operation (create, update, delete)
The approach, i.e. one of the 3 scenarios mentioned above
This is a sample of records in the database
In the CDK project, apart from the core stack, I create one stack for every approach. Each stack creates a configurable amount of custom resources, this number is set to 10.
These are all the stacks created by the project. If you deployed my code and you see many nested stacks with long names, flip the switch "View nested" to off to see only non-nested stacks.
The experiment has 3 phases
Deploy all stacks: trigger the creation of resources
Increment the version number and deploy again: trigger the update of resources
Delete the stacks from the CloudFormation console: trigger the deletion of resources
In the last step, I do not delete the core stack yet. The core stack contains the Database with the collected data.
It is time for the data to speak!
Scenario 1: Without dependencies
In this scenario, we do not enforce any dependencies between the resources.
The resources are created in no particular order, they are created in parallel.
I increment the version of the resources, which triggers an update. The updates happen in no particular order.
Finally, I delete the specific stack and the resources are deleted in parallel in no particular order.
Scenario 2: With dependencies
In this scenario, we use the DependsOn attribute
Resources: Resource2: ... Resource1: ... DependsOn: Resource2
or in CDK the equivalent is
Specifically, in our example, we create a chain of dependencies where
resource-(n+1) depends on
As we see in the data, the resources are created one by one in order from
The update is done in the same order from
while the deletion is performed in reverse order, i.e. starting with the last resource created
resource-10 and finishing with
Scenario 3: Nested stacks with dependencies
In this scenario, I place the resources within nested stacks. Nested stacks would usually contain several resources, but in this example, I only place a single resource per nested stack.
I create a similar chain of dependencies with scenario 2, but this time at the nested stack level. In CloudFormation this is done with the same
DependsOn attribute (a nested stack is just another resource in the parent stack).
In CDK, this is done like this
See here for the complete code of stack, including how to create nested stack with CDK.
Nested stacks are useful if your main CloudFormation stack is hitting one of the limits, e.g. size of the template or the number of resources per template.
Similarly to scenario 2, the resources are created in order from
Update of resources happens in the same order they have been created
and deletion happens in the reverse order, i.e. starting with the last resource created
Summary of results
In this post, I tested experimentally the order of creation/update/deletion of resources in CloudFormation.
When no dependencies are defined between resources, operations happen in parallel in no specific order.
Next, I defined dependencies using the
DependsOn attribute with 2 different approaches: dependencies at resource-level, or dependencies between nested stacks containing the resources.
A <- B <- C <- D (
B depends on
C depends on
B , ...), then in both approaches
Resources are created in order
Resources are updated in order
Resources are deleted in order