AWS VPC with public subnet ,private subnet and internet gateway by Terraform
Deepak Sharma
3 x RedHat Certified Engineer (EX200, EX294, EX180) || DevOps Engineer || Docker || K8s || Ansible || Linux || Git || Github || Gitlab || Terraform || Jenkins || Cloud Computing || AWS
In this article, we are going to look at how we can customize the setup of networking components and launch our own EC2 instances in our created vpc with private and public subnets.
Amazon Virtual Private Cloud (Amazon VPC) lets you provision a logically isolated section of the AWS Cloud where you can launch AWS resources in a virtual network that you define. You have complete control over your virtual networking environment, including selection of your own IP address range, creation of subnets, and configuration of route tables and network gateways.
OBJECTIVE
Our main objectives are as follows:
- Create a VPC, with 2 subnets — a public and private subnet.
- Create a public-facing Internet Gateway to connect the VPC to the outside world (Internet). Attach the gateway to the VPC we have created.
- Create a routing table for the Internet Gateway to allow instances launched in the public subnet to connect with the outside world. This is done by associating the routing table with the public subnet.
- Launch an AWS EC2 instance with WordPress setup on it on the public subnet. Also, attach a key to it. It must allow traffic through HTTP so that the clients can connect to the blog.
- Launch an AWS EC2 instance with MySQL setup on it on the private subnet. Also, attach a key to it. It must allow ingress only through port 3306 (default port to access MySQL database) and only the WordPress instances must be able to connect to the MySQL database.
Step-1 First create vpc
Vpc is provided by NAAS .In vpc ,we create two subnet :- public and private.At time of vpc creation ,we assign an IP range to vpc .
provider "aws" { region = "ap-south-1" profile = "deepak" } resource "aws_vpc" "main" { cidr_block = "192.168.0.0/16" enable_dns_hostnames=true enable_dns_support =true tags = { Name = "deepak-vpc" }
}
Here we give provider as AWS .So terraform download necessary plugins to contact with aws. In vpc ,we provides an cidr_block:-it is used to provides IP range.Now we launch an instance in this vpc ,then instance get IP in this range.Also enable dns_hostname ,so we can contact to instance either IP or dns_hostname.
Step-2 Create two subnets
Subnet have router,DHCP server that are connected switch .when we launch any instance inside subnet it will attach to switch and DHCP is the one who assign IP to this instance.
There may be many subnet inside VPC. These subnet having connectivity between them. Means instance in one subnet can connect to instance in another subnet.
We can’t directly launch instance in amazon data center. We have to launch it inside subnet. Subnet is inside any of the data center.When we create subnet , provides ip range within vpc IP range.In every subnet ,some IPs are reserved :-
- 1st IP = Network Name
- 2nd IP — Router
- 3rd IP — DHCP Server
- 4th IP — form some use case
- Last IP - Broadcasting
resource "aws_subnet" "public-subnet" { vpc_id = aws_vpc.main.id cidr_block = "192.168.0.0/24" map_public_ip_on_launch = true availability_zone = "ap-south-1a" tags = { Name = "public-subnet-1a" }
}
This is public subnet . Here we provides map_public_ip_on_launch = true . So when we launch instance ,it automatically get IP .
resource "aws_subnet" "private-subnet" { vpc_id = aws_vpc.main.id cidr_block = "192.168.1.0/24" map_public_ip_on_launch = false availability_zone ="ap-south-1b" tags = { Name = "private-subnet-1b" }
}
This is private subnet . Here we provides map_public_ip_on_launch = false . So when we launch instance ,it don't get IP and we are not able to connect it.
Step-3 Create Internet Gateway
Internet Gateway is the router in VPC . This router is Public Facing Router. From this Router from public can connect to instance running in subnet inside VPC . Through Internet gateway public can connect to inside vpc and subnet contact to outside world(public world). In technical words, an internet gateway serves two purposes: to provide a target in your VPC route tables for internet-routable traffic and to perform network address translation (NAT) for instances that have been assigned public IPv4 addresses.
resource "aws_internet_gateway" "gw" { vpc_id = aws_vpc.main.id tags = { Name = "My-internet-gateway" } }
This is our internet gateway which is attached to our created vpc.
Step-4 Create route table
Now we create route table .It is used to connect intenet gateway and subnet. We associate this route table only to public subnet.
# route table attach to our internet gateway resource "aws_route_table" "r" { vpc_id = aws_vpc.main.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.gw.id } tags = { Name = "my-routing-table" } } #route table connect to public subnet resource "aws_route_table_association" "a" { subnet_id = aws_subnet.public-subnet.id route_table_id = aws_route_table.r.id }
The route table must be created in relation to the Internet Gateway we have just created. Finally, the route table is associated with the public subnet, as only the public subnet must be allowed to have access to the Internet and the resources created in the private subnet are restricted from accessing the Internet.
Step-5 Launch mysql instance
Typically, it is hard to write rules for cases like those of the MySQL instances, as the security rules are often devised based on the IP addresses of the possible instances/users that can access them. However, in a dynamic setup, where the IP address can change (if we do not use Elastic IPs provided by AWS) and a variable number of instances themselves, using IP addresses is not feasible. So we use security group for this purpose.
- First create wordpress security group;- In this security group,we allow http port 80.So client can connect to instance.Also to give ourselves more power in handling the instances, we can enable SSH access through port 22.So in future ,we can ssh and resolve problem.
resource "aws_security_group" "web" { name = "wordpress-SG" description = "Allow HTTP and SSH inbound traffic" vpc_id = aws_vpc.main.id ingress { description = "HTTP" from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "SSH" from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "wordpress-SG" } }
2. Second create mysql security group;-In this we allow 3306 port to connect to mysql database. we can write rules for the security group of the MySQL instances based on the security groups of the WordPress instances. This means that only those EC2 instances with the security groups written for the WordPress instances will be allowed to access the MySQL instances.
resource "aws_security_group" "db" { name = "mysql-SG" description = "Allow webserver-SG inbound traffic" vpc_id = aws_vpc.main.id ingress { description = "MYSQL" security_groups = [aws_security_group.web.id] from_port = 3306 to_port = 3306 protocol = "tcp" } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "mysql-SG" }
}
3. Launch mysql instance in private subnet
Now we launch an ec2 instance which has MYSQL setup.This instance we attach with mysql-security group allowing port 3306 in private subnet so that our wordpress vm can connect with the same.
resource "aws_instance" "mysql" { ami = "ami-08706cb5f68222d09" instance_type = "t2.micro" associate_public_ip_address = false subnet_id = aws_subnet.private-subnet.id vpc_security_group_ids = [aws_security_group.db.id] tags ={ Name = "mysql" } }
Step-6 Launch wordpress instance
After security group created,we can launch wordpress instance .
resource "aws_instance" "wordpress" { ami = "ami-000cbce3e1b899ebd" instance_type = "t2.micro" associate_public_ip_address = true subnet_id = aws_subnet.public-subnet.id vpc_security_group_ids = [aws_security_group.web.id] key_name = "myfirstkey-pair" tags ={ Name = "wordpress" }
}
Wordpress instance is a part of public subnet so that our client can connect our site.We enable auto ip assign and auto dns name .So client can connect by Ip and dns_name.This wordpress instance is connected to mysql database and stored data inside it.
Now run the code :- To run terraform code ,we simply run
terraform init terraform apply
We see our vpc created ..
Our subnet ,both public and private are also created.
Now we can access the wordpress instance by ,its public ip .The home page of wordpress site ...
Finally task-3 has been completed of Hybrid Multi-Cloud Computing Program.
Thanks for reading article..