WEBVTT

00:00.660 --> 00:05.240
Now it's time to use Terraform
to deploy EC2 instances.

00:05.940 --> 00:10.260
To do this we'll make use of
the AWS instance type resource.

00:10.720 --> 00:13.260
Let's call the resource as web server.

00:14.180 --> 00:17.140
This resource expects
two mandatory arguments,

00:17.200 --> 00:21.720
the AMI, which is the AMI ID
in the US-West-1 region

00:21.720 --> 00:24.040
where we want to deploy the Ubuntu instance.

00:24.480 --> 00:26.680
The second is the instance type.

00:27.060 --> 00:32.460
We want to deploy a low spec instance
with just one CPU and 1 GB of Ram.

00:32.660 --> 00:36.820
We will opt for a t2.micro
general purpose instance type.

00:37.780 --> 00:42.300
Optionally, to identify the EC2 instance,
we can add tags to it

00:42.300 --> 00:45.420
by making use of the tags argument
which is a map.

00:45.780 --> 00:49.140
Here, we have added two tags in key value pairs.

00:49.500 --> 00:53.000
The first is the Name
with the value of web server.

00:53.640 --> 00:59.220
The next is the description which has a value
of an NGINX web server on Ubuntu.

01:00.080 --> 01:05.380
We can also pass in an entire bash shell script
to be run when the instance is launched.

01:05.580 --> 01:08.860
To do this, we'll make use of
the user data argument

01:08.860 --> 01:11.460
and the heredoc syntax, like this.

01:12.500 --> 01:14.600
We can now use the Terraform plan

01:14.600 --> 01:18.260
and then the apply command
to create the web server instance.

01:19.560 --> 01:22.960
All right, so we now have the instance
up and running,

01:22.960 --> 01:26.380
but how do we access it
from our client machine.

01:27.040 --> 01:29.620
Since this is an Ubuntu EC2 instance,

01:29.620 --> 01:33.520
the logical answer would be for us
to make use of an SSH client

01:33.520 --> 01:35.040
and then connect to the server,

01:35.400 --> 01:41.460
but what is the IP address of this machine
and how do we allow SSH access to it?

01:41.860 --> 01:45.080
Which SSH key do we use to connect to it?

01:45.580 --> 01:49.440
We have not specified any of these
in our Terraform configuration.

01:49.580 --> 01:53.780
As a result, by default,
we cannot access this from our client machine.

01:54.800 --> 01:59.220
In the demo where we created an EC2 instance
from the management console,

01:59.320 --> 02:03.440
we created an SSH key pair
just before launching the instance

02:03.440 --> 02:05.800
and we used this to connect to our server.

02:06.440 --> 02:09.400
Now, let's see how to do that with Terraform.

02:09.840 --> 02:12.900
Let's go back
and update our Terraform configuration.

02:13.360 --> 02:18.160
To do this, we'll make use of
another resource type called AWS key pair.

02:19.000 --> 02:23.280
This resource makes use of
an existing user supplied key pair

02:23.280 --> 02:26.960
that can be used to control the login
access to the EC2 instance.

02:27.640 --> 02:30.960
There's only one mandatory argument
called the public key

02:30.960 --> 02:33.760
and here, we are making use of the file function

02:33.760 --> 02:37.860
to read the contents of an existing public key
called web.pub

02:38.080 --> 02:41.040
which is stored in the local machine
running Terraform.

02:42.060 --> 02:46.140
Alternatively, we can also provide
the contents of the web.pub

02:46.140 --> 02:48.760
without using the file function, like this.

02:50.040 --> 02:54.500
Next, we can specify this key
within the AWS resource block

02:54.500 --> 02:57.660
by making use of the key name argument
like this.

02:58.880 --> 03:03.020
Now that we have added the key based
access control to our configuration,

03:03.080 --> 03:07.620
let us look at the networking that will allow
users to connect from the local machine

03:07.620 --> 03:10.940
to the port 22 on our web server
via the internet.

03:11.820 --> 03:15.140
In our demo,
when we we deployed the webserver manually,

03:15.140 --> 03:17.880
we saw that we used the default VPC

03:17.880 --> 03:21.300
and one of the available subnets
for the EC2 instance.

03:22.560 --> 03:27.280
Think of VPC as an isolated network
within your AWS infrastructure.

03:27.400 --> 03:30.900
Within this isolated network,
we can deploy services.

03:31.700 --> 03:35.840
With the VPC, we have the complete control
over the IP address range

03:35.840 --> 03:39.240
that can be assigned to a resource
such as an EC2 instance.

03:39.420 --> 03:42.880
We can also allow
and restrict access to this resource

03:42.880 --> 03:46.920
from other resources within the AWS cloud
or even the internet.

03:47.820 --> 03:52.420
In the demo, we also created
a new security group called SSH access,

03:52.580 --> 03:55.600
which as the name suggests, allows SSH access

03:55.600 --> 04:00.760
from any source
by making use of the 0.0.0/0 range.

04:01.280 --> 04:05.480
We then used the security group
while creating the web server instance.

04:06.120 --> 04:09.820
Although this is not a recommended approach
in a production scenario,

04:09.980 --> 04:14.500
this configuration will allow us to access
the Ubuntu webserver from the internet

04:14.500 --> 04:16.760
as long as we have the private key.

04:17.820 --> 04:20.900
Now let's do the same
with our Terraform configuration.

04:21.800 --> 04:26.280
We will deploy this instance in the default VPC
and subnet as in the demo,

04:26.280 --> 04:28.320
but we will create a security group

04:28.320 --> 04:31.900
that will allow ingress access to port 22
from the internet.

04:32.600 --> 04:37.500
For this, we have to make use of another
resource type called AWS security group.

04:38.260 --> 04:41.580
Let's call this resource as SSH access.

04:42.000 --> 04:46.120
The name and description are optional,
but we will give it some meaningful values

04:46.120 --> 04:49.580
such as SSH access for the name
and a suitable description.

04:50.620 --> 04:53.760
Now that we have added the resource block
for the security group,

04:53.760 --> 04:57.380
we have to apply it within the resource block
for the EC2 instance.

04:58.120 --> 05:03.000
To do this, we'll make use of the argument
called VPC security group IDs

05:03.280 --> 05:06.960
and use a reference expression
to specify the ID of the security group

05:06.960 --> 05:08.280
that we just configured.

05:09.000 --> 05:11.060
This argument expects a list.

05:11.060 --> 05:15.300
Make sure that the values are supplied
within square brackets like this.

05:16.720 --> 05:19.780
While we are at it, let's add an output variable

05:19.780 --> 05:22.820
to get the public IP address
of the webserver instance.

05:23.240 --> 05:27.400
We can use this later to SSH to the webserver
from our local machine.

05:28.740 --> 05:31.640
If we re-run the Terraform apply command now,

05:31.760 --> 05:35.580
we will see that the key pairs
and the security groups are created

05:35.580 --> 05:40.440
and the EC2 instance is recreated
because of the change in its configuration.

05:41.600 --> 05:43.500
Once the resources are created,

05:43.500 --> 05:48.840
we should be able to SSH to the webserver
instance using the private key like this.

