Setting up a three-tier architecture on AWS

Today, I am going to demonstrate how to use Virtual Private Cloud (VPC) services to setting up a three-tier architecture on Amazon Web Service (AWS). The architecture diagram below shows the setup, which is mainly divided into three layers.

diagram1.png

The first layer is the presentation layer. Users can directly access the public subnet through the gateway. The second layer is the logic layer, which mainly deals with business logic. In this layer, I put it on the private subnet to limit the access and put it behind the load balancer, which can be flexibly and horizontally expanded to handle different time periods with different traffic demands. The third layer is the data layer. In this private subnet, the MySQL database is deployed and only allowed access through the second layer. To improve availability, I deploy to two Availability Zones, and the database is backed up to the other Availability Zone, ensuring that in the event of a loss of one Availability Zone, application services can still be maintained.

First, I will create a VPC network, which I call victorleungtwdemo. According to the architecture diagram, I choose 172.17.0.0/16 and my large subnet segment has been created successfully. Notice here /16 subnet has a number of IP addresses 65535. If I set the subnet to /24, that is only 256 IP addresses. If I set it to the /28 subnet, it would be only 16 IP addresses, which would not be enough for future expansion.

diagram2.png

Next, I will create the subnets, I am going to create six subnets, the first subnet is called pub-subnet-1, and I must choose the previous created VPC, and then choose the right availability zone A. I first choose area A, then choose the right range of IP addresses. The VPC set-up as a /16 bit subnet and in order to consider scalability, I cannot block the subnet as it would have no scalability, therefore let me set a /24 subnet instead.

diagram3.png

And so on and so forth, I create the remaining five subnets. You can take a look at the diagram below, I have created six subnets. You can see the public subnet 1, the public subnet 2, the private subnets 1, 2, 3 and 4 as well as the corresponding Availability zones.

diagram4.png

Next, I would create the corresponding gateway. I create a new gateway victorleungtw-igw.

diagram5.png

After it is created, I can assign it to my VPC. Which VPC should I choose? Let's choose victorleungtwdemo VPC.

diagram6.png

Then you can take a look at the routing table. You can see that there is a default routing table after the VPC is created, which is the main routing table. You can click it and see the routing entries. When you create any route in the table, it has a default routing entry, which is also the first entry, that is to say, the subnets I create are all connected by default. You cannot delete or change this route.

Let's create a new routing table, the public pub-route can connect data to the public network and choose my victorleungtwdemo vpc, I will change the name of the original routing table to priv-route. For the subnet of the database, there should be no communication to this subnet from the Internet. Create another routing table, I call it nat-route, and I have chosen the right victorleungtwdemo VPC as well.

diagram7.png

At the moment, I already have three routing tables. You can see that it has a default route after creation.

diagram8.png

Let's specify the routes related to the public routing table pub-route and add a route 0.0.0.0/0 to the internet. I refer it to target victorleungtw-igw and then click save. In other words, all machines in this subnet will be able to access the public internet.

diagram9.png

Next, I am going to associate my public subnets. Which are my public subnets? Add pub-subnet-1 and pub-subnet-2.

diagram10.png

Then I add nat-route, and NAT related to priv-subnet-1 and priv-subnet-2.

diagram11.png

Lastly, I don’t need to worry about the remaining private routing table, since all subnets will go to the default routing table priv-route.

Then I will create a Network Address Translation (NAT) gateway. Let's choose a subnet and I choose priv-subnet-2. Because NAT must be allocated with Elastic IP (EIP), so I first create an EIP, and then we create a NAT gateway and add it to the routing table.

diagram12.png

Which routing table do we have? It is called the NAT routing table, add 0.0.0.0/0 from the nat gateway.

diagram13.png

So far, I have almost completed the network architecture with about 70 per cent. Next step, let's set up all the related security group settings. The security group must be bound to my VPC. When I create a VPC, there is a default security group. For example, I am going to use security group for my bastion and load balancer. My bastion allows only specific IP to access SSH port 22, and then my load balancer provides HTTP services to the outside world, so I have to open port 80. Then my web service should be allowed to be accessed by the load balancer, and a security group should also be created for my web server. Finally, for my database layer, I do not allow the bastion to access directly, but only the web layer is allowed to access my database.

Create bastion-sg which allows for ssh. Since it's for development purpose, I am going to set a wider range to 0.0.0.0/0, if it's production use, you may want to whitelist to your own IP address only.

diagram14.png

Create elb-sg which allows HTTP from anywhere.

diagram15.png

Create web-sg which allows traffic from my trusted elb-sg and bastion-sg

diagram16.png

Create db-sg which mysql 3306 traffic from web-sg only.

diagram17.png

Next, I need to start the relevant machines. Go to EC2, and use AMI Linux. Select, my VPC, let's create the bastion first, and I need the subnet corresponding to the bastion, pub-subnet-1. Enable auto-assign public IP and select the bastion-sg security group as shown in the diagram below.

diagram18.png

Create webserver1 in priv-subnet-1 with security group web-sg

diagram19.png

Create webserver2 in priv-subnet-2 with security group web-sg

diagram20.png

After creating all the web servers, I have to create an RDS server. Before creating the RDS server, I also need to create an RDS subnet group. Why? RDS is a little different from the EC2 setting we just set. When I create a new RDS, it does not allow me to choose which VPC. So we create another layer on existing subnet. Create victorleungtw-db subnet group, then select the subnet 172.17.4.0/24 and 172.17.5.0/24 as shown in the screenshot below.

diagram21.png

Next, create the database server as shown in the diagram below, notice we select the right vpc and the db-sg security group.

diagram22.png

diagram23.png

diagram24.png

diagram25.png

diagram26.png

Coming back to the EC2 instances, only the bastion server got public IP for access, while webserver 1 and 2 have no public IP address. I need to setup the target group for the webservers. Create a new target group victorleungtw-tg and add the two web servers as shown in the diagram below:

diagram27.png

diagram28.png

Then I would create a load balancer. Select application load balancer with name victorleungtw-alb and map to pub-subnet-1 and pub-subnet-2

diagram29.png

diagram30.png

diagram31.png

diagram32.png

Finally, everything is set up, we can test it out. Open a new terminal, ssh to the bastion host. Then from the bastion host, you could further ssh to webserver 1 and webserver 2 respectively. Start the Nginx server, and open a browser to access the elb url. You can verify by refreshing the page and hitting to the 2 servers with load balancing. From the web server, you can further verify to access the database from the application layer, but not from the bastion server layer.

That's it for setting up a 3 layer architecture on AWS. Let me know if you got any questions, feel free to connect