State Introduction
We will learn Terraform state, state file, why you need a state, and how you can speed up the Terraform project.
State#
The state is Terraform’s store of all of the resources it has created. State stores all of the information about the resources, including meta-information, that cannot be retrieved from APIs’ underlying infrastructure. It also stores the dependency order of the resources that it created.
Terraform uses its state to work out how it needs to make changes. By default, Terraform stores the state in a local file called terraform.tfstate
. You may have noticed this file in the examples we have been doing up until now.
Why Terraform needs to record the resources#
A common question is why Terraform needs to record the resources it has created in a state file? Why can’t it just look at the HCL code, compare that to the real world, and apply the changes? Well, there are quite a few reasons why Terraform would not work without its state file.
Resources drawback#
Some resources that you create have write-once values. Once they are written there is no way to retrieve them again. One such example is an RDS instance password. Imagine you created an RDS
instance with the password password123
. Terraform creates the RDS instance when you run it
and stores the password in its state file. If you then change the password to myPassword
in your HCL
code, Terraform would know to update the RDS instance because it would compare the password in
the state file to the one in the HCL code. If Terraform did not have its state file, it would have no way of knowing that you had changed the password as you cannot retrieve it back from the AWS
API.
State file#
Terraform also needs the state file for deleting resources. A simple example is if you had an AWS subnet and an EC2 instance in that subnet and wanted to delete both of them from your project.
Firstly, to delete something, Terraform needs to know that it created those resources in the first place. Terraform cannot assume that anything exists and therefore cannot destroy anything in AWS that is not in your HCL code.
Terraform also needs to know how to delete the EC2 instance before the subnet, since the instance depends on the subnet. When you create resources, Terraform finds out that the EC2 instance depends on the subnet through the referencing of a subnet’s output property as an input value into the EC2 instance subnet field. Thus it knows to create the subnet first. It then stores this dependency information in its state file. Subsequently, Terraform can use the dependency order in its state file to delete the resources in the correct order.
The only other way to solve this problem without a state file would be for Terraform to know the dependency order of all resource types. This quickly explodes to a point where it becomes almost impossible to maintain and does not scale.
Terraform uses the state to solve the dependency problem elegantly. This is a large part of why it is so important to make sure you reference resources in their dependencies in your HCL code. It is almost impossible for some resources not to do this as you cannot guess certain values before AWS creates them, such as an ID for a VPC.
Some resource values can, on the other hand, be guessed before they are created, such as the ARN of a resource. So even when you could compute the ARN and set it using a computed value, it is generally better to use the output property for the resource you want to reference.
Speed up the Terraform project#
By default, Terraform uses a combination of its state and the underlying infrastructure APIs to build its plan to achieve what you have specified in your HCL code. When projects reach a certain size, and due to rate limits imposed on some APIs, it can become impractical to interrogate them on every Terraform run.
In this situation, you can pass in a flag to Terraform to tell it to use its state as the source of truth. This greatly speeds up the Terraform run time. The downside of this approach is that if someone modifies the underlying infrastructure outside of Terraform, then the run could fail.