Dependency Graph

The Stack Engine's Dependency Graph and Execution Order

Template order means nothing. Every Ref, Fn::GetAtt or Fn::Sub reference, and every DependsOn, is an edge in a graph; a resource starts when everything it references is complete, unrelated resources start in parallel, and deletion runs backwards. cfn-lint 2,641 prints the graph (after pipx 21,050 inject cfn-lint pydot); the events show LocalStack 63,725 's order:

The dependency edges of graph.yaml, and LocalStack's creation orderYAML
cd ~/v5-ch7/booknest/infra
cfn-lint --build-graph graph.yaml
grep -- '->' graph.yaml.dot | sed -E 's/ \[.*label=(\w+).*/  (\1)/'
aws cloudformation describe-stack-events --stack-name booknest-graph --output text \
  --query "reverse(StackEvents)[?ResourceStatus=='CREATE_COMPLETE'].LogicalResourceId"
Output
ApiRole -> BooksTable  (GetAtt)
ApiRoleParam -> ApiRole  (GetAtt)
BooksTable   ApiRole   ApiRoleParam   FrontEndBucket   booknest-graph
graph.yaml's dependency graph: AWS starts independent resources together
graph.yaml's dependency graph: AWS 24 starts independent resources together

LocalStack's order is valid but serial, so its timings say nothing about AWS's. Add DependsOn only for dependencies CloudFormation 24 cannot see. A cycle, A referencing B and B referencing A, cannot be ordered, and cfn-lint rejects it as E3004 Circular Dependencies.