WEBVTT

00:00.380 --> 00:04.620
In this section, we will learn about
the difference between mutable

00:04.620 --> 00:06.680
and immutable infrastructure.

00:07.960 --> 00:12.740
In one of the previous lectures, we saw that
when Terraform updates a resource,

00:12.940 --> 00:16.140
such as updating the permissions
of a local file,

00:16.420 --> 00:20.420
it first destroys it and then recreates it
with the new permission.

00:21.300 --> 00:23.260
Why does Terraform do that?

00:23.960 --> 00:27.780
To understand this,
let us make use of a simple example.

00:28.500 --> 00:34.520
Consider an application server
running NGINX with the version of 1.17.

00:35.340 --> 00:38.000
When a new version of NGINX is released,

00:38.000 --> 00:40.760
we upgrade the software
running on this web server.

00:41.420 --> 00:45.440
First from 1.17 to 1.18.

00:45.680 --> 00:53.440
Eventually, when a new version 1.19 is released,
we upgraded the same way from 1.18 to 1.19.

00:54.340 --> 00:57.320
This can be done using
a number of different ways.

00:57.540 --> 01:01.660
One simple approach is to download
the desired version of NGINX

01:01.740 --> 01:06.180
and then use it to manually upgrade
the software on the web server

01:06.180 --> 01:07.840
during a maintenance window.

01:08.280 --> 01:12.580
Of course, we can also make use of
tools such as ad-hoc scripts,

01:12.580 --> 01:16.520
or configuration management tools
such as Ansible to achieve this.

01:17.740 --> 01:21.600
For high availability,
instead of relying on one web server,

01:21.600 --> 01:26.360
we can have a pool of these web servers
all running the same software and code.

01:27.500 --> 01:31.960
We would have to use the same software
upgrade lifecycle for each of the servers

01:31.960 --> 01:35.620
using the same approach
that we use for the first web server.

01:36.400 --> 01:40.000
This type of update is known as in-place update.

01:40.420 --> 01:44.000
This is because the underlying
infrastructure remains the same,

01:44.000 --> 01:46.700
but the software
and the configuration on these servers

01:46.700 --> 01:48.880
are changed as part of the update.

01:49.780 --> 01:53.540
This here is an example of
a mutable infrastructure.

01:54.520 --> 01:58.240
Updating software on a system
can be a complex task,

01:58.240 --> 02:02.460
and in almost all cases,
there are bound to be a set of dependencies

02:02.460 --> 02:06.300
that have to be met before an upgrade
can be carried out successfully.

02:06.940 --> 02:11.680
Let us assume that web server 1 and 2
have every dependency met

02:11.680 --> 02:15.580
while we try to upgrade the version
from 1.18 to 1.19.

02:16.460 --> 02:20.840
As a result, these two servers
are upgraded without any issues.

02:21.540 --> 02:24.400
Web server 3, on the other hand, does not.

02:24.960 --> 02:30.300
The upgrade fails on web server 3 because
it has a few dependencies that are not met,

02:30.300 --> 02:34.020
and as a result, it remains at version 1.18.

02:35.180 --> 02:38.720
A failure in upgrade could be
because of a number of reasons

02:38.720 --> 02:43.320
such as network issues impacting
the connectivity to the software repository,

02:43.700 --> 02:48.680
file system full, or different version of
operating system running on web server 3

02:48.680 --> 02:50.260
as compared to the other two.

02:50.720 --> 02:56.160
However, the important thing here to note is
that we now have a pool of three web servers

02:56.160 --> 02:59.880
in which one of the servers is running
a different version of software

02:59.880 --> 03:01.140
as compared to the rest.

03:02.280 --> 03:06.860
Over time, with multiple updates
and changes to this pool of servers,

03:06.940 --> 03:11.060
there is a possibility that each of the servers
vary from one another

03:11.220 --> 03:15.940
maybe in software, or configuration,
or operating system, et cetera.

03:16.740 --> 03:19.340
This is known as a configuration drift.

03:20.600 --> 03:25.760
For example, after a few update windows,
our three web servers could look like this.

03:26.240 --> 03:33.560
Web server 1 and 2 have NGINX version of 1.19,
and web server 3 has a version of 1.18.

03:34.480 --> 03:35.900
All three web servers

03:35.900 --> 03:40.160
may also be running slightly different
versions of operating system on them.

03:40.840 --> 03:44.960
This configuration drift can leave
the infrastructure in a complex state,

03:44.960 --> 03:48.720
making it difficult to plan
and carry out subsequent updates.

03:49.180 --> 03:52.300
Troubleshooting issues
would also be a difficult task

03:52.300 --> 03:55.780
as each server would behave
slightly differently from the other

03:55.780 --> 03:57.540
because of this configuration drift.

03:58.660 --> 04:01.980
Instead of updating the software versions
on the web servers,

04:01.980 --> 04:05.940
we can spin up new web servers
with the updated software version,

04:05.940 --> 04:08.460
and then delete the old web server.

04:09.400 --> 04:13.880
So when we want to update NGINX 1.17 to 1.18,

04:14.040 --> 04:18.100
a new server is provisioned
with 1.18 version of NGINX.

04:18.500 --> 04:22.420
If the update goes through,
then the old web server is deleted.

04:22.660 --> 04:25.460
This is known as immutable infrastructure.

04:25.860 --> 04:29.280
Immutable means unchanged
or something that you cannot change.

04:29.440 --> 04:32.360
As a consequence,
with immutable infrastructure,

04:32.360 --> 04:36.060
we cannot carry out in-place
updates of the resources anymore.

04:36.840 --> 04:41.480
This doesn't mean that updating web servers
this way will not lead to failures.

04:42.400 --> 04:46.940
If the upgrade fails for any reason,
the old web server will be left intact

04:46.940 --> 04:49.080
and the failed server will be removed.

04:50.540 --> 04:54.840
As a result, we do not leave much room
for configuration drift to occur

04:54.840 --> 04:56.080
between our servers,

04:56.080 --> 04:59.560
ensuring that it is left in a simple
easy-to-understand state.

05:00.780 --> 05:03.520
Since we are working with
Infrastructure as a Code,

05:03.520 --> 05:07.060
immutability makes it easier
to version the infrastructure

05:07.060 --> 05:10.140
and to roll back
and roll forward between versions.

05:11.580 --> 05:15.520
Terraform as an infrastructure
provisioning tool uses this approach.

05:16.580 --> 05:18.320
Going back to our example,

05:18.460 --> 05:21.700
updating the resource block
for our local file resource

05:21.700 --> 05:25.820
and changing the permission from 777 to 700

05:25.820 --> 05:28.660
will result in the original file to be deleted

05:28.660 --> 05:32.020
and a new file to be created
with the updated permission.

05:32.420 --> 05:35.740
By default, Terraform destroys
the resource first

05:35.740 --> 05:38.240
before creating a new one in its place.

05:39.240 --> 05:43.920
What if we want the resource to be created
first before the old one is deleted,

05:43.920 --> 05:46.200
or to ignore deletion completely?

05:47.020 --> 05:48.260
How do we do that?

05:48.860 --> 05:53.580
These can be done by making use of
lifecycle rules in our resource block,

05:53.580 --> 05:55.700
and we will see how to do that next.

