Create custom VPC with private and public subnets


 

Create a custom VPC with public and private subnets and run EC2 instances on it.

In this blog we will use AWS CLI version2 to create a custom VPC  along with private and public subnets and finally we will run new EC2 instances on this VPC.

To begin with, let's create a VPC with name as paulVPC2 and CIDR-Block range as 192.168.0.0/16 using below aws cli command

aws ec2 create-vpc ^
--cidr-block 192.168.0.0/16 ^
--tag-specifications="ResourceType=vpc,Tags=[{Key=Name,Value=paulVPC2}]"

The symbol '^' is used in windows for line continuation similar to '\' in linux.

To get the vpc-id of the above VPC use below aws cli command

aws ec2 describe-vpcs ^
--output json

In this VPC we will create a subnet with name=paulSubnet1 in Mumbai 1a AZ

aws ec2 create-subnet ^
--cidr-block 192.168.1.0/24 ^
--vpc-id vpc-0855a7ab2ac29fb28 ^
--availability-zone ap-south-1a ^
--tag-specifications="ResourceType=subnet,Tags=[{Key=Name,Value=paulSubnet1}]"

Inside this subnet we can run new EC2 instances but before that we have to create security groups with all protocols by default allowed.

aws ec2 create-security-group ^
--description "All access"  ^
--group-name sg4customVPC ^
--vpc-id vpc-0855a7ab2ac29fb28 ^
--tag-specifications="ResourceType=security-group,Tags=[{Key=Name,Value=allowAll}]" 

Next add a rule in this security group which will allow anyone (0.0.0.0/0) to come via all protocols and ports

aws ec2 authorize-security-group-ingress ^
--group-id sg-0b3dbf3d6924dec61 ^
--protocol all ^
--port -1 ^
--cidr 0.0.0.0/0 

After this, we will create our first EC2 instance inside above subnet and VPN. We will use Amazon Linux 2 AMI and associate a public ip to this instance.

aws ec2 run-instances ^
--image-id ami-04b1ddd35fd71475a ^
--instance-type t2.micro ^
--key-name "EC2 Tutorial" ^
--security-group-ids sg-0b3dbf3d6924dec61  ^
--subnet-id subnet-0f6cc91ad6c2dc043 ^
--count 1 ^
--associate-public-ip-address 

Change --key-name to your available Key Pair.

To get security group and subnet ids use below commands

aws ec2 describe-security-groups

and

aws ec2 describe-subnets

We can connect this VPN to internet using Internet Gateway. So first create an Internet Gateway with name=paulIGW2 using below command

aws ec2 create-internet-gateway ^
--tag-specifications="ResourceType=internet-gateway,Tags=[{Key=Name,Value=paulIGW2}]" 

Attach this Internet Gateway to above VPC

aws ec2 attach-internet-gateway ^
--internet-gateway-id igw-0464090d4b734bf20 ^
--vpc-id vpc-0855a7ab2ac29fb28 

To list all available Internet Gateways use

aws ec2 describe-internet-gateways

Add a route in the routing table of 1st subnet (paulSubnet1) that specifies the default gateway to internet. It's recommended to create a new routing table for the subnet.

aws ec2 create-route-table ^
--vpc-id vpc-0855a7ab2ac29fb28 ^
--tag-specifications="ResourceType=route-table,Tags=[{Key=Name,Value=RT4paulSubnet1}]" 

Add route to this routing table for default gateway.

aws ec2 create-route ^
--route-table-id rtb-073e9cf6dcf1bc8ed ^
--destination-cidr-block 0.0.0.0/0 ^
--gateway-id igw-03c646ec6c69a1c16  

Here 0.0.0.0/0 means from anywhere and to list out available routing tables use below command

aws ec2 describe-route-tables

Now attach this new routing table to above subnet

aws ec2 associate-route-table  ^
--route-table-id rtb-073e9cf6dcf1bc8ed ^
--subnet-id subnet-0051c09e819b4ff95 ^

Now try to ping the public ip of the 1st EC2 instance created above

ping 65.0.91.2

Also try to connect to this EC2 instance.

In this way we can create a public subnet. Now let's create a private subnet. Give CIDR-Block=192.168.2.0/24 and availability-zone=ap-south-1b. Make sure the CIDR-Block for each subnet must be within the range of VPN CIDR-Block.

aws ec2 create-subnet ^
--cidr-block 192.168.2.0/24 ^
--vpc-id vpc-0855a7ab2ac29fb28 ^
--tag-specifications="ResourceType=subnet,Tags=[{Key=Name,Value=paulSubnet2}]" ^
--availability-zone ap-south-1b 

Create 2nd EC2 instance (paulOS2) in 2nd subnet and also upload Key pair (in this case "EC2 Tutorial") in the 1st EC2 instance (paulOS1) using WinSCP tool and then try to ssh into 2nd EC2 instance from 1st EC2 instance. WinSCP tool supports only ppk format and not pem format files. Follow below series of snapshots





We want the 2nd EC2 instance (paulOS2) to be able to connect to internet but no one from outside this VPC can connect to it. For this we will use a NAT Gateway.

First create an Elastic ip address using below command

aws ec2 allocate-address --domain vpc 

Then create a NAT Gateway using this Elastic ip address as below

aws ec2 create-nat-gateway ^
--subnet-id subnet-0051c09e819b4ff95 ^
--allocation-id eipalloc-086160d4bdee16225 ^
--tag-specifications="ResourceType=natgateway,Tags=[{Key=Name,Value=paulNATgw1}]"

Create a new route table to associate it with 2nd subnet which will have the rule to use NAT Gateway to access internet

aws ec2 create-route-table ^
--vpc-id vpc-0855a7ab2ac29fb28 ^
--tag-specifications="ResourceType=route-table,Tags=[{Key=Name,Value=RT4paulSubnet2}]" 

Add one route to this route table to use NAT Gateway to access internet by EC2 instances belonging to private subnet

aws ec2 create-route ^
--route-table-id rtb-0f021882561aef15a ^
--destination-cidr-block 0.0.0.0/0 ^
--nat-gateway-id nat-06783d8eb0b19215d

Use below command to get NAT Gateway id

aws ec2 describe-nat-gateways

Finally associate this new route table with 2nd subnet (paulSubnet2)

aws ec2 associate-route-table ^
--route-table-id rtb-0f021882561aef15a ^
--subnet-id subnet-0f6cc91ad6c2dc043

Now we are able to connect to internet from 2nd EC2 instance without having public ip by the use of NAT gateway.



A real world use case for the above setup would be a multi tier architecture where we will have one custom VPC consisting of one public and one private subnets.

We can create an EC2 instance in the public subnet which will act as a PHP server and another EC2 instance in the private subnet which will act as the Database server.


Happy Learning

 

Comments

Popular posts from this blog

How to create an AWS EC2 instance