I want to begin with a quote from Wikipedia on finite-state machines:
A finite-state machine (FSM) or finite-state automaton, finite automaton, or simply a state machine, is a mathematical model of computation. It is an abstract machine that can be in exactly one of a finite number of states at any given time. The FSM can change from one state to another in response to some inputs; the change from one state to another is called a transition. An FSM is defined by a list of its states, its initial state, and the inputs that trigger each transition.
At a first glance, this does not sound like a Terraform configuration. Let’s break it down!
A […] state machine, is a mathematical model of computation. […]
Terraform is not mathematics. At least most of us have way more fun using Terraform than using math, so the conclusion must be that Terraform is not mathematics. However, Terraform takes input and produces and output. This is exactly what functions in mathematics do.
It is an abstract machine that can be in exactly one of a finite number of states at any given time
Every Terraform configuration has an initial state that is just an empty state file. But what are the possible states that the Terraform configuration can be in? This depends a little bit on what we consider to be a state. Are we talking about the state file and what it contains? Or are we talking about the Terraform worklow where your Terraform configuration is used?
In the case of the contents of the state file, then the “finite number of states” is a vast space of states. For a provider with a single resource with a single name
argument that accepts a string of at most 10 characters we will have:
\(Total = N^1 + N^2 + … + N^{10}\)
Where N is the number of acceptable characters (e.g. maybe the resource only accepts lowercase letters). The number of possible states blows up when we consider that a provider has many resource types, each accepting multiple arguments, and each argument accepting many valid values.
In the second case we instead consider the Terraform workflow. Here there are fewer states to consider.
A new Terraform configuration does not have any state. From there it has to move to the initialized state. Once it is initialized it can move to the planned state. Technically it could move back to nothing, by deleting the .terraform
directory and the dependency lock file. However, you can’t do that transition using the Terraform binary.
From the planned state it can move to the applied state. Once it has been applied it can be applied again and again (technically via another plan, but not the same planned state as before because we can’t move back to the initialized state from this new planned state) or it can move to the destroyed state. In a sense, the destroyed state is the same as the initialized state.
It is clear that there is some confusion around the states, where some states are technically the same.
The FSM can change from one state to another in response to some inputs; the change from one state to another is called a transition.
This is clearly true. You change the Terraform state (either of the two types we just discussed) by providing inputs (e.g. variables or new resources) and you apply them. This makes the state transition from A to B.
An FSM is defined by a list of its states, its initial state, and the inputs that trigger each transition.
This is true, but once again it is not straight-forward to define the list of possible states. The initial state is easy: it’s just nothing. The inputs that trigger transitions is also hard to enumerate if we consider the state to be what is inside the state file. There are potentially an infinite amount of possible inputs. But in the case of the workflow state it is easier, the input is just what CLI command we are running (e.g. run apply
on a plan to transition from planned to applied).
I like the idea of considering the contents of the state file in my state machine, even if it quickly gets out of hand. If we limit the scope of the infrastructure we allow the Terraform configuration to contain, then we could call it a state machine.
If we had something like a dummy provider with a single resource:
resource "dummy_resource" "default" {
a = "a"
b = 1
}
This resource type has to attributes, a
and b
. a
accepts a single lowercase letter between a and z. b
accepts a number between 0 and 9. We can update the values of this resource however we want and re-apply.
Our initial state would be an empty state. Nothing. As for all Terraform configurations.
The number of possible states would be \(10 * 26 = 260\) (assuming there are 26 letters from a to z).
The inputs that trigger each transition are the values of a
and b
.
In conclusion: yes, your Terraform configuration is a state machine. It might be hard to define it considering the number of possible states.
What does this mean? Nothing really. I just had this idea and wanted to see where it would take me!