Now it's time to use Terraform to deploy EC2 instances.
To do this we'll make use of the AWS instance type resource.
Let's call the resource as web server.
This resource expects two mandatory arguments,
the AMI, which is the AMI ID in the US-West-1 region
where we want to deploy the Ubuntu instance.
The second is the instance type.
We want to deploy a low spec instance with just one CPU and 1 GB of Ram.
We will opt for a t2.micro general purpose instance type.
Optionally, to identify the EC2 instance, we can add tags to it
by making use of the tags argument which is a map.
Here, we have added two tags in key value pairs.
The first is the Name with the value of web server.
The next is the description which has a value of an NGINX web server on Ubuntu.
We can also pass in an entire bash shell script to be run when the instance is launched.
To do this, we'll make use of the user data argument
and the heredoc syntax, like this.
We can now use the Terraform plan
and then the apply command to create the web server instance.
All right, so we now have the instance up and running,
but how do we access it from our client machine.
Since this is an Ubuntu EC2 instance,
the logical answer would be for us to make use of an SSH client
and then connect to the server,
but what is the IP address of this machine and how do we allow SSH access to it?
Which SSH key do we use to connect to it?
We have not specified any of these in our Terraform configuration.
As a result, by default, we cannot access this from our client machine.
In the demo where we created an EC2 instance from the management console,
we created an SSH key pair just before launching the instance
and we used this to connect to our server.
Now, let's see how to do that with Terraform.
Let's go back and update our Terraform configuration.
To do this, we'll make use of another resource type called AWS key pair.
This resource makes use of an existing user supplied key pair
that can be used to control the login access to the EC2 instance.
There's only one mandatory argument called the public key
and here, we are making use of the file function
to read the contents of an existing public key called web.pub
which is stored in the local machine running Terraform.
Alternatively, we can also provide the contents of the web.pub
without using the file function, like this.
Next, we can specify this key within the AWS resource block
by making use of the key name argument like this.
Now that we have added the key based access control to our configuration,
let us look at the networking that will allow users to connect from the local machine
to the port 22 on our web server via the internet.
In our demo, when we we deployed the webserver manually,
we saw that we used the default VPC
and one of the available subnets for the EC2 instance.
Think of VPC as an isolated network within your AWS infrastructure.
Within this isolated network, we can deploy services.
With the VPC, we have the complete control over the IP address range
that can be assigned to a resource such as an EC2 instance.
We can also allow and restrict access to this resource
from other resources within the AWS cloud or even the internet.
In the demo, we also created a new security group called SSH access,
which as the name suggests, allows SSH access
from any source by making use of the 0.0.0/0 range.
We then used the security group while creating the web server instance.
Although this is not a recommended approach in a production scenario,
this configuration will allow us to access the Ubuntu webserver from the internet
as long as we have the private key.
Now let's do the same with our Terraform configuration.
We will deploy this instance in the default VPC and subnet as in the demo,
but we will create a security group
that will allow ingress access to port 22 from the internet.
For this, we have to make use of another resource type called AWS security group.
Let's call this resource as SSH access.
The name and description are optional, but we will give it some meaningful values
such as SSH access for the name and a suitable description.
Now that we have added the resource block for the security group,
we have to apply it within the resource block for the EC2 instance.
To do this, we'll make use of the argument called VPC security group IDs
and use a reference expression to specify the ID of the security group
that we just configured.
This argument expects a list.
Make sure that the values are supplied within square brackets like this.
While we are at it, let's add an output variable
to get the public IP address of the webserver instance.
We can use this later to SSH to the webserver from our local machine.
If we re-run the Terraform apply command now,
we will see that the key pairs and the security groups are created
and the EC2 instance is recreated because of the change in its configuration.
Once the resources are created,
we should be able to SSH to the webserver instance using the private key like this.