We now have a pretty good idea about
how to get started with Terraform.
We have learned how to write simple configuration
files using HCL,
declare and use variables,
use reference expressions,
and link resources together.
Now
let's get introduced to Terraform state
and see what really happens under
the hood when we run Terraform commands
to provision infrastructure.
Before we understand Terraform state,
let us see the Terraform workflow once again.
We have a configuration files
in a directory called terraform-local-file.
The main Terraform configuration with the resource blocks
is defined in the file called main.tf.
The variables used
are defined inside the file called variables.tf.
At this point,
we do not have the local file resource created.
First,
we'll run the terraform init command
to download the necessary plugins.
Next,
we can generate the execution plan
by running the terraform plan command.
The very first line that is
printed when we run this command
shows that Terraform tries to
refresh the state in-memory prior to the plan.
Since it's the first time we are running
the terraform plan command,
there will be no details related to a state printed,
therefore implying that there is no state
recorded at this moment in time.
From this,
Terraform also understands that
currently there are no resources provisioned
based on the configuration files,
and then
creates an execution plan of create.
Moving on,
let us now run terraform apply.
This command also tries
to refresh the in-memory state,
finds that there is no state recorded at the moment,
and then proceeds to create an execution plan.
Once confirmed,
Terraform creates the local file resource as expected.
Terraform creates a unique ID
for the resource as seen in the command output.
As expected,
we can see that the file has been created
with the content that we provided.
Now,
what will happen if you
run the terraform apply command again?
Terraform knows that a local file
resource by the name of pet
and the same ID that we just saw
already exists
and it takes no further action.
So
How does Terraform know that?
How does it know that the local file resource already exists?
To understand that,
let us check the contents of the configuration directory again.
We can now see that there is an additional file
called terraform.tfstate created in this directory.
This file is called the terraform state file,
which was created as a consequence
of the terraform apply command
that created the resource in the first place.
This file is not created
until the terraform apply command is run at least once.
The state file is a JSON data structure
that maps the real-world infrastructure resources
to the resource definition in the configuration files.
If we inspect the contents of this state file,
we can see that it has the complete
record of the infrastructure created by Terraform.
In this case,
we have a single resource
of type local file
and a logical name called pet.
The details such as the resource ID,
provider information,
and all the resource attributes are stored within this file.
It contains
every little detail pertaining to the
infrastructure that was created by Terraform,
and it uses it
as a single source of truth
when using commands such as terraform plan and apply.
If we make a change to the configuration file now,
and rerun the terraform plan
or apply command,
Terraform by default refreshes the state again
and compares it against the configuration file.
It now knows that the resource argument called content
has a different value in the configuration file
as compared to the terraform state and the real world.
The configuration value uses the string
"We love pets!" for the content argument,
but the state file record shows that the
actual content in this file is "I love pets!"
As a result,
Terraform knows that the resource must be recreated
and when we run terraform apply,
it updates the state file as well.
From the output of the apply command,
we can see that the older local_file
resource with the older ID is deleted
and replaced with a new resource with
a completely different ID with the updated content.
The same can be seen in the terraform state file as well.
It no longer has
a reference for the older resource ID
and now has the details recorded for
the replaced file resource.
At this point in time,
the configuration file
and the state file are in sync,
and since they do not have any differences,
there will be no changes to apply subsequently.
The example we have used here
contains only a single resource
and the same is reflected in the terraform state file.
In a real-world scenario,
a terraform configuration may contain
numerous resources belonging to several different providers.
Irrespective of the size of the infrastructure,
Terraform will always create a state file
and use it to store information about
the state of the infrastructure in the real world.
It is non-optional.
In the upcoming lectures,
we will see why state is so important in Terraform.