├── happy.png
├── toplevel.png
├── all-states.png
├── create-stack.png
├── delete-stack.png
├── update-stack.png
├── Makefile
├── toplevel.dot
├── delete-stack.dot
├── happy.dot
├── create-stack.dot
├── update-stack.dot
├── all-states.dot
├── toplevel.svg
├── delete-stack.svg
├── README.md
├── happy.svg
├── create-stack.svg
├── update-stack.svg
└── all-states.svg
/happy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rvedotrc/aws-cloudformation-stack-states/HEAD/happy.png
--------------------------------------------------------------------------------
/toplevel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rvedotrc/aws-cloudformation-stack-states/HEAD/toplevel.png
--------------------------------------------------------------------------------
/all-states.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rvedotrc/aws-cloudformation-stack-states/HEAD/all-states.png
--------------------------------------------------------------------------------
/create-stack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rvedotrc/aws-cloudformation-stack-states/HEAD/create-stack.png
--------------------------------------------------------------------------------
/delete-stack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rvedotrc/aws-cloudformation-stack-states/HEAD/delete-stack.png
--------------------------------------------------------------------------------
/update-stack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rvedotrc/aws-cloudformation-stack-states/HEAD/update-stack.png
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | DOTS := $(shell echo *.dot)
2 | PNGS := $(patsubst %.dot, %.png, $(DOTS))
3 | SVGS := $(patsubst %.dot, %.svg, $(DOTS))
4 |
5 | default: all
6 |
7 | all: $(PNGS) $(SVGS)
8 |
9 | %.png: %.dot
10 | dot -Tpng -o$@.tmp $< && mv $@.tmp $@
11 |
12 | %.svg: %.dot
13 | dot -Tsvg -o$@.tmp $< && mv $@.tmp $@
14 |
15 | delete:
16 | rm -f $(PNGS) $(SVGS)
17 |
18 | clean:
19 | rm -f *.png *.svg
20 | $(MAKE) all
21 |
22 |
--------------------------------------------------------------------------------
/toplevel.dot:
--------------------------------------------------------------------------------
1 | digraph toplevel {
2 |
3 | before_existence [ label="no stack" ]
4 | after_existence [ label="no stack" ]
5 |
6 | CREATED
7 | DELETED
8 | UPDATED
9 |
10 | before_existence -> CREATED
11 |
12 | CREATED -> UPDATED
13 | UPDATED -> UPDATED
14 |
15 | UPDATED -> DELETED
16 |
17 | CREATED -> DELETED
18 | DELETED -> after_existence [ label=" 90 days later" ]
19 |
20 | }
21 | // # vi: set sw=2 et ai :
22 |
--------------------------------------------------------------------------------
/delete-stack.dot:
--------------------------------------------------------------------------------
1 | digraph delete_stack {
2 |
3 | after_existence [ layer="happy" label="no stack" ]
4 |
5 | deletable_stack [ label="stack\n(various states)" color="transparent" ]
6 |
7 | DELETE_COMPLETE [ layer="happy" ]
8 | DELETE_FAILED [ layer="sad" ]
9 | DELETE_IN_PROGRESS [ layer="happy" style=dotted ]
10 |
11 | deletable_stack -> DELETE_IN_PROGRESS -> try_delete -> check_delete
12 | try_delete [ shape="rect" label="Try deleting each resource\nthat has not already been\ndeleted (but see also the\nDeletionPolicy)" ]
13 | check_delete [ shape="diamond" label="Did the deletes\nall succeed?" ]
14 | check_delete -> DELETE_COMPLETE [ label="yes" ]
15 | check_delete -> DELETE_FAILED [ label="no" ]
16 |
17 | DELETE_FAILED -> deletable_stack [ constraint="false" ]
18 | DELETE_COMPLETE -> after_existence [ label=" 90 days later" ]
19 |
20 | }
21 | // # vi: set sw=2 et ai :
22 |
--------------------------------------------------------------------------------
/happy.dot:
--------------------------------------------------------------------------------
1 | digraph happy {
2 |
3 | before_existence [ label="no stack" ]
4 | after_existence [ label="no stack" ]
5 |
6 | REVIEW_IN_PROGRESS [ style=dotted ]
7 | CREATE_COMPLETE
8 | CREATE_IN_PROGRESS [ style=dotted ]
9 | DELETE_COMPLETE
10 | DELETE_IN_PROGRESS [ style=dotted ]
11 | UPDATE_COMPLETE
12 | UPDATE_COMPLETE_CLEANUP_IN_PROGRESS [ style=dotted label="UPDATE_COMPLETE\nCLEANUP_IN_PROGRESS" ]
13 | UPDATE_IN_PROGRESS [ style=dotted ]
14 |
15 | before_existence -> CREATE_IN_PROGRESS
16 | before_existence -> REVIEW_IN_PROGRESS -> CREATE_IN_PROGRESS
17 | CREATE_IN_PROGRESS -> CREATE_COMPLETE
18 |
19 | REVIEW_IN_PROGRESS -> DELETE_COMPLETE // never fully created
20 |
21 | CREATE_COMPLETE -> UPDATE_IN_PROGRESS -> UPDATE_COMPLETE_CLEANUP_IN_PROGRESS -> UPDATE_COMPLETE
22 | UPDATE_COMPLETE -> UPDATE_IN_PROGRESS
23 |
24 | UPDATE_COMPLETE -> DELETE_IN_PROGRESS
25 |
26 | CREATE_COMPLETE -> DELETE_IN_PROGRESS
27 | DELETE_IN_PROGRESS -> DELETE_COMPLETE
28 | DELETE_COMPLETE -> after_existence [ label=" 90 days later" ]
29 |
30 | }
31 | // # vi: set sw=2 et ai :
32 |
--------------------------------------------------------------------------------
/create-stack.dot:
--------------------------------------------------------------------------------
1 | digraph create_stack {
2 |
3 | before_existence [ label="no stack" ]
4 |
5 | REVIEW_IN_PROGRESS [ style=dotted ]
6 | CREATE_COMPLETE
7 | CREATE_IN_PROGRESS [ style=dotted ]
8 | CREATE_FAILED
9 | ROLLBACK_COMPLETE
10 | ROLLBACK_FAILED
11 | ROLLBACK_IN_PROGRESS [ style=dotted ]
12 |
13 | before_existence -> CREATE_IN_PROGRESS -> try_creates -> check_creates
14 | before_existence -> REVIEW_IN_PROGRESS -> CREATE_IN_PROGRESS
15 | try_creates [ shape="rect" label="Try creating the resources\n(respecting the dependency order)" ]
16 | check_creates [ label="Did the creates all succeed?" shape="diamond" ]
17 | check_creates -> CREATE_COMPLETE [ label="yes" ]
18 | check_creates -> do_we_need_rollback [ label="no" ]
19 | do_we_need_rollback [ shape="diamond" label="Did any of the creates succeed?" ]
20 | do_we_need_rollback -> CREATE_FAILED [ label="no" ]
21 | do_we_need_rollback -> ROLLBACK_IN_PROGRESS [ label="yes" ]
22 |
23 | ROLLBACK_IN_PROGRESS -> try_deletes -> check_deletes
24 | try_deletes [ shape="rect" label="Try deleting the resources\n(respecting the dependency order)" ]
25 | check_deletes [ shape="diamond" label="Did the deletes all succeed?" ]
26 | check_deletes -> ROLLBACK_COMPLETE [ label="yes" ]
27 | check_deletes -> ROLLBACK_FAILED [ label="no" ]
28 |
29 | // But would be useful to document: for each of those terminal states, what
30 | // states are the resources in? What happens to the stack next?
31 |
32 | // Resource statuses include:
33 | // CREATE_COMPLETE, UPDATE_COMPLETE, DELETE_COMPLETE, DELETE_FAILED, DELETE_SKIPPED.
34 |
35 | }
36 | // # vi: set sw=2 et ai :
37 |
--------------------------------------------------------------------------------
/update-stack.dot:
--------------------------------------------------------------------------------
1 | digraph update_stack {
2 |
3 | CREATE_COMPLETE
4 | UPDATE_COMPLETE
5 | UPDATE_COMPLETE_CLEANUP_IN_PROGRESS [ style=dotted label="UPDATE_COMPLETE\nCLEANUP_IN_PROGRESS" ]
6 | UPDATE_IN_PROGRESS [ style=dotted ]
7 | UPDATE_ROLLBACK_COMPLETE
8 | UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS [ style=dotted label="UPDATE_ROLLBACK_COMPLETE\nCLEANUP_IN_PROGRESS" ]
9 | UPDATE_ROLLBACK_FAILED
10 | UPDATE_ROLLBACK_IN_PROGRESS [ style=dotted ]
11 |
12 | { CREATE_COMPLETE, UPDATE_COMPLETE } -> UPDATE_IN_PROGRESS -> try_rollforward_creates_and_updates -> check_rollforward_creates_and_updates
13 | try_rollforward_creates_and_updates [ shape="rect" label="Run the ROLLFORWARD plan\n(creates + updates)" ]
14 | check_rollforward_creates_and_updates [ label="Did the rollforward creates\n& updates all succeed?" shape="diamond" ]
15 | check_rollforward_creates_and_updates -> UPDATE_COMPLETE_CLEANUP_IN_PROGRESS [ label="yes (or no-op)" ]
16 | check_rollforward_creates_and_updates -> UPDATE_ROLLBACK_IN_PROGRESS [ label="no" ]
17 |
18 | UPDATE_COMPLETE_CLEANUP_IN_PROGRESS -> try_rollforward_cleanup -> check_rollforward_cleanup
19 | try_rollforward_cleanup [ shape="rect" label="Run the ROLLFORWARD plan\n(deletes)" ]
20 | check_rollforward_cleanup [ shape="diamond" label="Did the rollforward\ndeletes all succeed?" ]
21 | check_rollforward_cleanup -> UPDATE_COMPLETE_3 [ label="yes (or no-op)" ]
22 | check_rollforward_cleanup -> UPDATE_ROLLBACK_IN_PROGRESS [ label="no" ]
23 | UPDATE_COMPLETE_3 [ label="UPDATE_COMPLETE" ]
24 |
25 | UPDATE_ROLLBACK_IN_PROGRESS -> try_rollback_creates_and_updates -> check_rollback_creates_and_updates
26 | try_rollback_creates_and_updates [ shape="rect" label="Run the ROLLBACK plan\n(creates + updates)" ]
27 | check_rollback_creates_and_updates [ label="Did the rollback creates\n& updates all succeed?" shape="diamond" ]
28 | check_rollback_creates_and_updates -> UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS [ label="yes (or no-op)" ]
29 | check_rollback_creates_and_updates -> UPDATE_ROLLBACK_FAILED [ label="no" ]
30 |
31 | UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS -> try_rollback_cleanup -> check_rollback_cleanup
32 | try_rollback_cleanup [ shape="rect" label="Run the ROLLBACK plan\n(deletes)" ]
33 | check_rollback_cleanup [ shape="diamond" label="Did the rollback\ndeletes all succeed?" ]
34 | check_rollback_cleanup -> UPDATE_ROLLBACK_COMPLETE [ label="yes (or no-op)" ]
35 | check_rollback_cleanup -> UPDATE_ROLLBACK_FAILED [ label="no" ]
36 |
37 | // But would be useful to document: for each of those terminal states, what
38 | // states are the resources in? What happens to the stack next?
39 |
40 | }
41 | // # vi: set sw=2 et ai :
42 |
--------------------------------------------------------------------------------
/all-states.dot:
--------------------------------------------------------------------------------
1 | digraph all_states {
2 |
3 | node [layer=all];
4 | edge [layer=all];
5 |
6 | layers="happy:sad"
7 |
8 | before_existence [ layer="happy" label="no stack" ]
9 | after_existence [ layer="happy" label="no stack" ]
10 |
11 | updateable_stack [ layer="happy" label="an updateable stack\n(various states)" color="transparent" ]
12 | stuck_stack [ layer="sad" label="a non-updateable stack\n(various states)" color="transparent" ]
13 | empty_stack [ layer="sad" label="non-deleted stack\nwith no extant resources\n(various states)" color="transparent" ]
14 |
15 | empty_stack -> DELETE_IN_PROGRESS [ layer="sad" ]
16 |
17 | CREATE_COMPLETE [ layer="happy" ]
18 | REVIEW_IN_PROGRESS [ layer="happy" style=dotted ]
19 | CREATE_IN_PROGRESS [ layer="happy" style=dotted ]
20 | CREATE_FAILED [ layer="sad" ]
21 | DELETE_COMPLETE [ layer="happy" ]
22 | DELETE_FAILED [ layer="sad" ]
23 | DELETE_IN_PROGRESS [ layer="happy" style=dotted ]
24 | ROLLBACK_COMPLETE [ layer="sad" ]
25 | ROLLBACK_FAILED [ layer="sad" ]
26 | ROLLBACK_IN_PROGRESS [ layer="sad" style=dotted ]
27 | UPDATE_COMPLETE [ layer="happy" ]
28 | UPDATE_COMPLETE_CLEANUP_IN_PROGRESS [ layer="happy" style=dotted label="UPDATE_COMPLETE\nCLEANUP_IN_PROGRESS" ]
29 | UPDATE_IN_PROGRESS [ layer="happy" style=dotted ]
30 | UPDATE_ROLLBACK_COMPLETE [ layer="sad" ]
31 | UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS [ layer="sad" style=dotted label="UPDATE_ROLLBACK_COMPLETE\nCLEANUP_IN_PROGRESS" ]
32 | UPDATE_ROLLBACK_FAILED [ layer="sad" ]
33 | UPDATE_ROLLBACK_IN_PROGRESS [ layer="sad" style=dotted ]
34 |
35 | edge [layer=happy];
36 | before_existence -> CREATE_IN_PROGRESS
37 | before_existence -> REVIEW_IN_PROGRESS -> CREATE_IN_PROGRESS
38 | CREATE_IN_PROGRESS -> CREATE_COMPLETE
39 | CREATE_COMPLETE -> updateable_stack
40 |
41 | REVIEW_IN_PROGRESS -> DELETE_COMPLETE
42 |
43 | edge [layer=sad];
44 | CREATE_IN_PROGRESS -> ROLLBACK_IN_PROGRESS -> ROLLBACK_COMPLETE
45 | ROLLBACK_COMPLETE -> empty_stack
46 | ROLLBACK_IN_PROGRESS -> ROLLBACK_FAILED
47 | ROLLBACK_FAILED -> stuck_stack
48 |
49 | edge [layer=sad];
50 | CREATE_IN_PROGRESS -> CREATE_FAILED // ?
51 | CREATE_FAILED -> empty_stack // ?
52 | stuck_stack -> DELETE_IN_PROGRESS
53 |
54 | edge [layer=happy];
55 | updateable_stack -> UPDATE_IN_PROGRESS -> UPDATE_COMPLETE_CLEANUP_IN_PROGRESS -> UPDATE_COMPLETE -> updateable_stack
56 |
57 | edge [layer=sad];
58 | { UPDATE_IN_PROGRESS, UPDATE_COMPLETE_CLEANUP_IN_PROGRESS } -> UPDATE_ROLLBACK_IN_PROGRESS -> UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS -> { UPDATE_ROLLBACK_COMPLETE, UPDATE_ROLLBACK_FAILED }
59 | UPDATE_ROLLBACK_COMPLETE -> updateable_stack
60 | UPDATE_ROLLBACK_IN_PROGRESS -> UPDATE_ROLLBACK_FAILED -> stuck_stack // maybe?
61 | UPDATE_ROLLBACK_FAILED -> UPDATE_ROLLBACK_IN_PROGRESS
62 |
63 | edge [layer=happy];
64 | updateable_stack -> DELETE_IN_PROGRESS
65 | DELETE_IN_PROGRESS -> DELETE_COMPLETE
66 | DELETE_COMPLETE -> after_existence [ label=" 90 days later" ]
67 |
68 | edge [layer=sad];
69 | DELETE_IN_PROGRESS -> DELETE_FAILED [ constraint="false" ]
70 | DELETE_FAILED -> stuck_stack
71 |
72 | }
73 | // # vi: set sw=2 et ai :
74 |
--------------------------------------------------------------------------------
/toplevel.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
70 |
--------------------------------------------------------------------------------
/delete-stack.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
92 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | AWS CloudFormation Stack States
2 | ===============================
3 |
4 | The [AWS CloudFormation documentation](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)
5 | includes a [list of all the possible stack states](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-describing-stacks.html):
6 |
7 | * `CREATE_COMPLETE`
8 | * `CREATE_IN_PROGRESS`
9 | * `CREATE_FAILED`
10 | * `DELETE_COMPLETE`
11 | * `DELETE_FAILED`
12 | * `DELETE_IN_PROGRESS`
13 | * `REVIEW_IN_PROGRESS`
14 | * `ROLLBACK_COMPLETE`
15 | * `ROLLBACK_FAILED`
16 | * `ROLLBACK_IN_PROGRESS`
17 | * `UPDATE_COMPLETE`
18 | * `UPDATE_COMPLETE_CLEANUP_IN_PROGRESS`
19 | * `UPDATE_IN_PROGRESS`
20 | * `UPDATE_ROLLBACK_COMPLETE`
21 | * `UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS`
22 | * `UPDATE_ROLLBACK_FAILED`
23 | * `UPDATE_ROLLBACK_IN_PROGRESS`
24 |
25 | However, it does not make it clear how the states relate to each other.
26 |
27 | This document aims to rectify that.
28 |
29 | *Caveat lector*: This document reflects *my understanding* of AWS
30 | CloudFormation. It is not definitive. I do not work for AWS. I've been
31 | using CloudFormation for a few years now, but there are features of it that
32 | I've not yet used. For all of those reasons, this document may not be 100%
33 | accurate.
34 |
35 | But I hope that it's helpful.
36 |
37 | With that said, let's get going.
38 |
39 | High-Level View
40 | ---------------
41 |
42 | At a high level, the lifecycle of a stack is:
43 |
44 | * the stack initially does not exist;
45 | * the stack is created;
46 | * the stack is updated (0 or more times);
47 | * the stack is deleted;
48 | * the stack finally does not exist.
49 |
50 | which you can visualise as follows:
51 |
52 | 
53 |
54 | However, "CREATED", "UPDATED" and "DELETED" are not real stack states – just a
55 | simplified model. So let's talk specifics.
56 |
57 | The Happy Path
58 | --------------
59 |
60 | If we ignore all the error cases, the state diagram is as follows:
61 |
62 | 
63 |
64 | * the stack initially does not exist;
65 | * the stack is created:
66 | * by first passing through `CREATE_IN_PROGRESS`
67 | * before coming to rest at `CREATE_COMPLETE`;
68 | * zero or more times, the stack is updated, where each update consists of:
69 | * first passing through `UPDATE_IN_PROGRESS`
70 | * then passing through `UPDATE_COMPLETE_CLEANUP_IN_PROGRESS`
71 | * before coming to rest at `UPDATE_COMPLETE`;
72 | * the stack is deleted:
73 | * by first passing through `DELETE_IN_PROGRESS`
74 | * before coming to rest at `DELETE_COMPLETE`;
75 | * the stack finally does not exist.
76 |
77 | A couple of things to note here:
78 |
79 | Firstly, each stack state can be considered either to be "in motion" (all the stacks named `..._IN_PROGRESS`), or "at rest" (everything else).
80 |
81 | Secondly, note that once a stack has been deleted (`DELETE_COMPLETE`), the
82 | stack remains present in AWS CloudFormation for the next 90 days, so that the
83 | stack's metadata and events (log) can be inspected. After 90 days, the stack
84 | disappears from CloudFormation.
85 |
86 | There's also the `REVIEW_IN_PROGRESS` state, which (when used) sits right near the top,
87 | just after "the stack initially does not exist", but before
88 | `CREATE_IN_PROGRESS`. `REVIEW_IN_PROGRESS` is used if the stack is created
89 | via a change set.
90 |
91 | But: what about the error cases?
92 |
93 | Error Handling
94 | --------------
95 |
96 | Let's complete the diagram by adding in all the states related to error
97 | handling:
98 |
99 | 
100 |
101 | To make the diagram simpler, I've added a few "pseudo-states", to represent
102 | abstract concepts like "a stack is updateable". I've also assumed that some
103 | of the states that *can* be passed through are (in a manner of speaking)
104 | *always* passed through, even if the stack might spend zero time in that
105 | state.
106 |
107 | To break this down, let's look at how stacks are created, updated, and deleted.
108 |
109 | Change Sets
110 | -----------
111 |
112 | Part of CloudFormation's job is to work out "how to get there from here" –
113 | what resource creations, updates and deletes need to happen, and in what
114 | order, to reach the requested outcome.
115 |
116 | The CreateStack, UpdateStack and DeleteStack API calls all make use of this
117 | approach: validate the request, work out what changes will be required, then
118 | make those changes. The [Change Sets API calls](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-changesets.html)
119 | can be used to inspect the planned changes before they are performed.
120 |
121 | The changes always break down into:
122 |
123 | * 0 or more resource creates / updates;
124 | * followed by 0 or more resource deletions.
125 |
126 | Some "updates" can be performed by updating the existing resources in-place;
127 | some work by doing a create of a new resource, then deleting the old one.
128 |
129 | If anything goes wrong, then CloudFormation may attempt to roll back to the
130 | previous steady state. This is done essentially by replaying the steps done
131 | so far, but in reverse order, and with the sense of all the changes reversed
132 | (create instead of delete, and vice versa).
133 |
134 | CreateStack
135 | -----------
136 |
137 | For stack creation, the planned changes will always consist of resource
138 | creations only (no updates, no deletes):
139 |
140 | 
141 |
142 | If anything goes wrong, then any resources that *were* created need to be
143 | deleted (the `ROLLBACK_IN_PROGRESS` / `ROLLBACK_FAILED` / `ROLLBACK_COMPLETE`
144 | states).
145 |
146 | UpdateStack
147 | -----------
148 |
149 | UpdateStack is the most complex case, because it may include resource creates,
150 | updates, and deletes. And if anything goes wrong, this means that the
151 | rollback too might involve deletes, updates, and creates:
152 |
153 | 
154 |
155 | If a stack reaches the `UPDATE_ROLLBACK_FAILED` state, the options are to
156 | attempt deletion (`DELETE_IN_PROGRESS`), re-attempt rollback
157 | (`UPDATE_ROLLBACK_IN_PROGRESS`), or to contact AWS support. See
158 | [the AWS blog post on "continue update rollback"](https://aws.amazon.com/blogs/devops/continue-rolling-back-an-update-for-aws-cloudformation-stacks-in-the-update_rollback_failed-state/)
159 | for more information.
160 |
161 | DeleteStack
162 | -----------
163 |
164 | DeleteStack is reasonably straightforward; for each resource that is not
165 | already deleted, and for which the
166 | [DeletionPolicy](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html)
167 | says to delete the resource, the resource deletion will be attempted. In case
168 | of problems, rollback (i.e. recreating resources) is *not* performed.
169 |
170 | 
171 |
172 | If there are problems, the stack goes to the `DELETE_FAILED` state. Once the
173 | reason for the deletion failure has been identified and fixed, `DeleteStack`
174 | can be called again to re-try the deletion of any resources that have not yet
175 | been deleted.
176 |
177 |
--------------------------------------------------------------------------------
/happy.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
154 |
--------------------------------------------------------------------------------
/create-stack.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
178 |
--------------------------------------------------------------------------------
/update-stack.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
207 |
--------------------------------------------------------------------------------
/all-states.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
359 |
--------------------------------------------------------------------------------