WEBVTT

00:00.513 --> 00:03.233
Let us now recap provisioners
in Terraform.

00:06.060 --> 00:08.800
Provisioners provide a way for us
to carry out tasks

00:08.886 --> 00:12.013
such as running commands or scripts
on remote resources

00:12.306 --> 00:15.040
or locally on the machine
where Terraform is installed.

00:15.886 --> 00:19.486
For example, to run a bash script
after a resource is created,

00:19.960 --> 00:22.526
we can make use
of the remote exec provisioner.

00:23.333 --> 00:26.860
Using the same web server example
that we have seen many times so far,

00:27.180 --> 00:29.760
we can pass in an inline script like this.

00:30.766 --> 00:34.300
As you can see from this example,
the provisional block goes

00:34.426 --> 00:36.140
directly inside a resource block.

00:37.086 --> 00:40.946
These commands in the inline list
will now be run on the remote instance

00:41.026 --> 00:42.346
after it is deployed.

00:42.513 --> 00:46.320
In this example, we are running an app
to update, installing, enabling,

00:46.406 --> 00:49.886
and starting engine X on the EC2 instance
after it is deployed.

00:50.626 --> 00:53.326
However, keep a note
that nearly specifying

00:53.466 --> 00:55.706
the provisional block with the script
will not guarantee

00:55.786 --> 00:57.306
that the commands will work.

00:57.640 --> 01:00.240
For it to work,
there should be network connectivity

01:00.326 --> 01:02.866
between the local machine
and the remote instance.

01:03.200 --> 01:06.173
For Linux instances,
this means an SSH connection

01:06.453 --> 01:09.853
and if it's Windows,
WINRM connectivity should be established.

01:10.266 --> 01:13.440
Now this can be achieved by making use
of appropriate security groups

01:13.526 --> 01:15.546
while creating the remote resources.

01:16.593 --> 01:19.520
In this case, we are creating
the security group resource,

01:19.766 --> 01:22.013
but it could also be
an existing security group

01:22.160 --> 01:24.373
that's already available
in the AWS account.

01:25.586 --> 01:28.513
There should also be
authentication mechanism that can be used

01:28.606 --> 01:30.193
to connect to these instances.

01:30.446 --> 01:34.340
Most commonly an SSH key pair
that can be used to access the instance.

01:34.773 --> 01:38.886
Again, in this example, we are using
an SSH key pair in the resource definition.

01:39.453 --> 01:42.446
Now this key is created
by the AWS keeper resource,

01:42.633 --> 01:46.400
but it could also be an existing key pair,
which is available in the account.

01:48.600 --> 01:51.226
To facilitate the authentication,
we can make use

01:51.333 --> 01:53.266
of the connection block like this.

01:54.213 --> 01:59.660
This is an example of a Linux based AMI
as such the connection type is set to SSH.

02:00.646 --> 02:03.940
The host argument
is where we specify the public IP address

02:04.026 --> 02:07.506
of the instance that was created
and since we are operating directly

02:07.586 --> 02:10.573
inside the resource block,
we can make use of an expression,

02:10.840 --> 02:12.973
self.public_ip like this.

02:14.126 --> 02:17.173
This will effectively translate
into the public IP address

02:17.253 --> 02:18.940
of the instance that was provisioned.

02:19.606 --> 02:23.113
The user in this case is Ubuntu
as that's the default user created

02:23.220 --> 02:27.066
within this AMI and the key we use
to connect to is the private key.

02:27.493 --> 02:30.880
Remember that earlier we used
the public key pair as an argument

02:30.980 --> 02:32.313
while creating the resource.

02:32.986 --> 02:37.000
Now, when we run Terraform apply,
we should see the remote exec provisioner

02:37.086 --> 02:40.086
connecting to the instance
using the details of the connection block

02:40.286 --> 02:43.020
and completing the task specified
in the inline list.

02:44.513 --> 02:47.233
Next, let's take a look
at the local exec provisioner.

02:48.120 --> 02:51.573
Local exec provisioner is used
to run tasks on the local machine

02:51.653 --> 02:54.926
where we are running the Terraform binary
and not on the resources

02:55.013 --> 02:56.640
which are created by Terraform.

02:57.253 --> 03:00.413
This is especially handy
when we want to gather some data

03:00.493 --> 03:02.140
and write into a file locally.

03:02.753 --> 03:05.913
For example,
if you want to store the public IP address

03:06.033 --> 03:08.266
of the EC 2 instance,
that was just provisioned

03:08.480 --> 03:12.326
into a file called IP.text
in the slash [?] file system,

03:12.673 --> 03:17.840
we can run the local exec provisioner
like this and just like we saw

03:17.926 --> 03:21.200
with the remote exec provisioner,
the provisional block for local exec

03:21.300 --> 03:23.306
also goes inside the resource block.

03:24.346 --> 03:27.213
Once the resource is created
after a Terraform apply,

03:27.406 --> 03:30.106
we can see the public IP address
recorded into the file.

03:31.913 --> 03:35.326
By default, provisioners are run
after the resources are created.

03:35.740 --> 03:38.193
This is the default behavior,
and it is called

03:38.273 --> 03:40.166
as a create time provisioner.

03:42.740 --> 03:46.013
We can also make provisioner run
before a resource is destroyed.

03:46.306 --> 03:48.453
This is called
a destroyed time provisioner.

03:49.146 --> 03:52.846
Now this can be specifically set
by making use of the event argument

03:53.033 --> 03:56.573
and specifying its value as destroyed
within the provisional block.

03:59.473 --> 04:03.246
Another default behavior of provisioner
is that if the command or script

04:03.340 --> 04:06.993
within the provisional block fails,
the Terraform apply operation

04:07.073 --> 04:08.173
also errors out.

04:09.500 --> 04:12.966
In this example, an incorrect part
using the command causes the script

04:13.073 --> 04:14.993
to fail and results in an error.

04:16.080 --> 04:19.366
This is the default provisional behavior,
but it can also be set

04:19.446 --> 04:21.933
by specifically mentioning
on failure argument

04:22.013 --> 04:24.120
inside the provisional block like this.

04:25.106 --> 04:28.033
Any resource that is created
while the provisional fails is marked

04:28.173 --> 04:29.760
as tainted within Terraform.

04:30.693 --> 04:33.820
For the Terraform apply operation
to not fail and the resource

04:33.906 --> 04:36.606
to be created successfully
even if the provisioner command

04:36.686 --> 04:38.906
of script fails,
we can set the value

04:38.986 --> 04:41.753
of the on failure argument
to continue like this.

04:44.393 --> 04:47.380
As the best practice,
Terraform recommends to use provisionals

04:47.466 --> 04:51.813
as a last resort, wherever possible,
make use of options natively available

04:51.913 --> 04:53.946
for resource types for the provider used.

04:54.460 --> 04:58.753
For example, use user data
while creating an EC2 two instance in AWS

04:59.266 --> 05:05.220
and custom data for Azure virtual machines,
metadata for GCP, et cetera.

