Terraform code to create a VPC , Subnet , EC2 Instance , keypairs , Security group and Nat Gateway with Website Hosting in AWS
Tags: terraform, linux, aws, devops
Published: 2022-10-09 16:35:25

**In a DevOps scenario, building AWS services via tools like Terraform is a more scalable and automated approach to cloud resource provisioning.**

## Understanding AWS VPCs
**An AWS VPC is a single network that allows you to launch AWS services within a single isolated network. Technically, an AWS VPC is almost the same as owning a datacenter but with built-in additional benefits of scalability, fault-tolerance, unlimited storage, etc.**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6e1aa4trkkedc9xdvncc.png)

## Building the Terraform Configuration for an AWS VPC
**1. To start, create a folder to store your Terraform configuration files in. This tutorial will create a folder called terraform-ec2 in your home directory.**


## The Terraform configuration below:

**Creates a VPC**
**Creates an Internet Gateway and attaches it to the VPC to allow traffic within the VPC to be reachable by the outside world.**
**Creates a public and private subnet**

```
Subnets are networks within networks. They are designed to help network traffic flow be more efficient and provide smaller, more manageable ‘chunks’ of IP addresses
```

**Creates a route table for the public and private subnets and associates the table with both subnets**
**Creates a NAT Gateway to enable private subnets to reach out to the internet without needing an externally routable IP address assigned to each resource.**
**Creates two server/instance [ public and private ]**
**Deploy a website inside public server with the help of scripting file [.sh].**


**Create a file inside ~/terraform-ec2 directory, paste in the following code, and name it as provider.tf to define the AWS provider**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tn11pldpsm1jq40t93q.png)

**Vars.tf is a Terraform variables file that contains all the variables that the configuration file references.**
**You can see variables references in the configuration file by:**

```
variable "region" {}
 variable "main_vpc_cidr" {}
 variable "public_subnets" {}
 variable "private_subnets" {}
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vorfrufztng9vks19eaa.png)

**Create one more file inside the ~/terraform-ec2 directory, name it terraform.tfvars, and paste the code below. This variables file contains the values that Terraform will use to replace the variable references inside of the configuration file.**

```
main_vpc_cidr = "11.0.0.0/16"
 public_subnets = "11.0.1.0/24"
 private_subnets = "11.0.2.0/24"
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wriyb02jpnkuhzfx6rj.png)

**The instance.tf file contains all the resources which are required to be provisioned such as vpc subnets and instance.**

**Creating VPC & Internet Gateway.**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j974hi9el8k7nwo7tanl.png)

**Creating public and private subnets**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0sy3yxsxfraiinrjin2.png)

**Creating routes table for public and private subnets**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykh1ub48ahgq143s6rcu.png)

**Subnets association and Creating Nat gateway**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w557qxjxqib75ie4l3s0.png)

**Creating keypairs for Ec2 instances**
**To create a key inside our folder we need to type following commands**

```
ssh-keygen -t rsa
./id_rsa
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ce7eckipqad0xbaozy4z.png)
**It will create two files id_rsa[private] and id_rsa.pub[public]**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a8wezqb5ahcjsk8tv6ok.png)

**Creating a web_server.sh file for Website deployment**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrbk8i966lwc2b7bixzq.png)

**Creating EC2 public server with keys pair**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5nljsauaxe2gz09kf00e.png)

**Creating EC2 private server**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kx7fgiq9l1b2mw0x3gb.png)

**Creating Security Groups and assign it to EC2 instance** 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a442ng5pns0007czfo61.png)
 
**Run the terraform init command in the same directory. The terraform init command initializes the plugins and providers which are required to work with resources.**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpvxk0p8qeh714g57vxd.png)

**Now, run the terraform plan command. This is an optional, yet recommended action to ensure your configuration’s syntax is correct and gives you an overview of which resources will be provisioned in your infrastructure**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ldn1n5wfasa2cc1isv3c.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qe6mvxz6cthjtzr1fi5h.png)

**Next, tell Terraform actually to provision the AWS VPC and resources using terraform apply. When you invoke terraform apply, Terraform will read the configuration (instance.tf) and the other files to compile a configuration. It will then send that configuration up to AWS as instructions to build the VPC and other components.**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lev236zem17awl2onmm6.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c6x12jj3712xwxo25jyt.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h9ql6zpomcw7rna8r2vf.png)

**Now our resources are created successfully lets verify it in aws console**

**VPC**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ry1lu45wvupglcp1uywp.png)
**Subnets**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akpvlejlzzcuoeazg7e1.png)
**Routes tables**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67z8icz8r2ozfs2r2pnu.png)
**Internet gateway**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vnkwq2j52jf30gmukk2x.png)
**Nat Gateway**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oivcmqtxgwupp6ncn6nr.png)
**Public & private servers**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lo11jzpcdd2v5tpt03yo.png)

**Put your public server ip in browser and check your website**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4x98r82l3vnw1s4j2b72.png)

**You can also try to ssh into public server**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ul8ybdqoszu1khwgwt7w.png)

**As private server don't have any public ip...so inorder to ssh into it we can either use openvpn or a jump server [ so here public server acts like a jump server]**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3dwffnexvaarm05guqe4.png)

**Now we are in private server.. we can't able ping as there is no internet inside this server**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3tlyvljobfkx9n3whkz.png)

**Using Nat gateway we can go to internet from this server** 
**A NAT gateway is a Network Address Translation (NAT) service. You can use a NAT gateway so that instances in a private subnet can connect to services outside your VPC but external services cannot initiate a connection with those instances.**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/432gm7gxwyn7wf6kw9nk.png)

**Now you can delete all resources at a time using terraform destroy commands.**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5333whj5chac3k72ou5q.png)

**The terraform destroy command is a convenient way to destroy all remote objects managed by a particular Terraform configuration.**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5epn8am8pbtal0imqa00.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4tklbkeg8u1ucitqw7vg.png)