WEBVTT

00:00.540 --> 00:04.900
In this lecture, we will get introduced
to a remote state in Terraform.

00:06.120 --> 00:09.460
Previously, we saw how Terraform
uses the state file

00:09.460 --> 00:13.900
to map resources in the configuration file
to real world infrastructure.

00:15.440 --> 00:18.220
So far, we have been working
with the Terraform state file

00:18.220 --> 00:19.640
that is stored locally.

00:20.200 --> 00:22.900
When we run Terraform apply for the first time,

00:22.900 --> 00:25.880
a file called terraform.tfstate is created

00:25.880 --> 00:28.700
inside the configuration directory
by default.

00:29.840 --> 00:32.480
Some of the benefits of
the Terraform state are,

00:32.580 --> 00:36.120
mapping Terraform configuration
to the real world infrastructure,

00:36.580 --> 00:39.100
tracking metadata such as dependencies,

00:39.100 --> 00:42.860
which allow Terraform to create
and delete resources in the correct order,

00:43.100 --> 00:45.700
improving the performance
of Terraform operations

00:45.700 --> 00:48.080
while working with
large configuration files

00:48.080 --> 00:52.320
and especially those that make use of
a number of different cloud providers.

00:53.180 --> 00:57.140
Finally, the Terraform state allows
members of a team to collaborate

00:57.140 --> 00:59.140
and provision resources as a team.

01:00.020 --> 01:02.980
However, in the examples
that we have seen so far,

01:03.140 --> 01:06.400
Terraform state file is created locally
on the client machine

01:06.580 --> 01:09.660
and more specifically
within the configuration directory

01:09.660 --> 01:11.660
that is being used as a default.

01:12.280 --> 01:15.120
This is an example of a local state file,

01:15.120 --> 01:18.520
and it does not provide
a good opportunity to collaborate.

01:18.740 --> 01:22.620
This is because the file is only available
on the client machine,

01:22.620 --> 01:24.620
such as a developer's laptop.

01:25.700 --> 01:29.320
We have also learned that
unlike the configuration files,

01:29.320 --> 01:33.400
it's not a good idea to store the state file
in a version control system.

01:33.560 --> 01:37.140
This is because it would mostly contain
sensitive information

01:37.140 --> 01:38.920
pertaining to our infrastructure.

01:39.600 --> 01:44.280
Let us see why it's a bad idea to store
the state file in a version control system.

01:44.760 --> 01:49.740
For this, let's see the Terraform workflow
when used individually and as a team

01:49.740 --> 01:52.980
with the state and configuration
saved within a Git Repo.

01:54.100 --> 01:56.860
Let us consider that Abdul, who is a developer,

01:57.060 --> 02:00.580
writes the Terraform configuration
for creating an S3 bucket.

02:01.200 --> 02:03.740
He then proceeds to run the Terraform plan.

02:03.940 --> 02:08.460
After reviewing the execution plan,
proceeds to apply the configuration.

02:09.100 --> 02:14.520
At this stage, Terraform creates
a local state file called terraform.tfstate.

02:15.300 --> 02:17.220
Once the bucket has been created,

02:17.220 --> 02:21.640
he checks in all the files in
the configuration directory into a Git Repo,

02:21.640 --> 02:23.640
including the Terraform state file

02:24.240 --> 02:28.140
and if any changes are to be made,
the same process is repeated.

02:28.340 --> 02:30.760
The files are fetched from the Git Repo,

02:30.860 --> 02:33.180
changes are then made
to the configuration file.

02:33.360 --> 02:36.260
This is followed by a Terraform plan
and then apply.

02:37.200 --> 02:41.920
Finally, the updated configuration file
and the state are pushed to the Git Repo.

02:43.140 --> 02:45.540
Now, let us assume that the team is growing

02:45.540 --> 02:50.060
and a new developer called Lee also wants to
manage the infrastructure using Terraform.

02:50.960 --> 02:56.000
The logical way would be for Lee to pull down
the Git Repo into his own client machine.

02:56.380 --> 03:00.520
He would then follow the same process as Abdul
to make changes to the infrastructure,

03:00.780 --> 03:03.180
make changes to the configuration as needed,

03:03.180 --> 03:06.500
review the execution plan
and then apply the configuration.

03:07.000 --> 03:10.760
Once applied, he would make sure
to push the updated configuration

03:10.760 --> 03:13.000
and state file into the remote Git Repo.

03:13.760 --> 03:18.360
While this can technically work, there are
some major flaws when using this approach.

03:19.020 --> 03:23.540
As we saw earlier, state file stores
all the information about the infrastructure,

03:23.540 --> 03:29.060
including IP addresses, initial passwords
for some databases, key names, et cetera.

03:29.360 --> 03:33.240
Keeping all this information
in a Git repository is not recommended.

03:34.220 --> 03:36.640
Secondly, when we work as a team,

03:36.640 --> 03:39.680
it is important that
only one person runs operation

03:39.680 --> 03:43.020
against the same configuration
and state at any given time.

03:43.480 --> 03:48.060
If Abdul and Lee both try to update
the same S3 bucket at the same time

03:48.060 --> 03:51.960
using the exact same state file
but within their individual laptops,

03:51.960 --> 03:56.320
it can lead to unintended consequences
such as the corruption of the state file.

03:57.340 --> 04:00.240
When using local state files as an individual,

04:00.360 --> 04:03.240
Terraform protects itself
from getting into the situation

04:03.240 --> 04:06.620
where concurrent operations are run
against the same configuration,

04:06.620 --> 04:10.600
and this can be tested by running
Terraform operations one after the other,

04:10.920 --> 04:14.740
such as running data from apply command
simultaneously from two terminals.

04:16.060 --> 04:20.180
While the first operation is in progress,
Terraform locks the state file.

04:20.180 --> 04:24.560
As a consequence, we will not be able to run
any operation from the second terminal

04:24.560 --> 04:26.680
until the first operation finishes.

04:27.640 --> 04:31.520
This is a very important feature
of Terraform called state locking.

04:31.640 --> 04:34.540
It ensures that the state file
does not get corrupted

04:34.540 --> 04:37.800
by multiple operations trying to update it
at the same time.

04:38.680 --> 04:42.720
Version control systems such as GitHub
do not support state locking.

04:42.880 --> 04:46.120
As a result, if it is used to store the state file,

04:46.120 --> 04:49.660
multiple users can use the same state file
simultaneously,

04:49.660 --> 04:53.880
which can result in issues like conflicts
and data loss within the state file.

04:54.660 --> 04:58.640
Finally, if a user forgets to pull
the latest version of the state file

04:58.640 --> 05:03.020
from the version control system
and work with an older obsolete state file,

05:03.020 --> 05:06.500
it can result in disastrous ethics
such as rollback

05:06.500 --> 05:08.500
or even destroying of the resources.

05:09.700 --> 05:11.660
Because of all these reasons,

05:11.660 --> 05:16.200
it's a much better option to store
Terraform state in a secure, shared storage

05:16.200 --> 05:18.360
by making use of remote backends.

05:19.140 --> 05:23.600
With this option, the state file no longer
resides in the configuration directory

05:23.600 --> 05:25.160
or version control systems

05:25.160 --> 05:29.720
and are moved to a shared storage solution
such as AWS S3,

05:29.720 --> 05:33.860
HashiCorp Consul, Google cloud storage
and Terraform cloud.

05:35.280 --> 05:37.280
When a remote backend is configured,

05:37.280 --> 05:40.860
Terraform will automatically load
the state file from the shared storage

05:40.860 --> 05:43.800
every time it is required
by a Terraform operation.

05:44.400 --> 05:49.080
It will also upload the updated
Terraform state file after every apply.

05:49.540 --> 05:53.300
Most importantly,
many of these remote backend options

05:53.300 --> 05:56.540
such as the AWS S3 allows for state locking.

05:57.180 --> 06:00.820
This ensures that the integrity
of the state file is maintained.

06:01.840 --> 06:05.960
Finally, the remote backends provide
different ways to secure the storage

06:05.960 --> 06:08.620
such as encryption at rest and in transit

06:08.620 --> 06:12.960
to make sure that all the sensitive
information stored inside is secured.

06:14.020 --> 06:17.500
In the next lecture, we will see
how to configure remote backends

06:17.500 --> 06:19.500
using AWS S3.

