Designing a Robust Cloud Infrastructure with AWS Three-Tier Architecture ๐ŸŒš

ยท

9 min read

Designing a Robust Cloud Infrastructure with AWS Three-Tier Architecture ๐ŸŒš

Hello everyone!๐Ÿ’ซ Are you ready to learn more about the amazing world of cloud infrastructure and its capabilities? Grab your coffee โ˜•๏ธ and let's get started, shall we?


Understanding the Three-tier Architecture ๐Ÿ‘€

The three-tier architecture is a popular architectural design pattern that divides an application into three separate components: the web server tier, the application server tier, and the database server tier. Each component has specific roles that together allow for the secure and efficient delivery of applications to users at scale.

When implementing such an architecture on Amazon Web Services (AWS) cloud infrastructure, you need to understand the role of each component, how they interact with each other, and the infrastructure services that power them. This includes the Elastic Load Balancer (ELB) for routing requests between tiers, Auto Scaling Group (ASG) for creating and managing identical copies of compute instances, and Amazon Relational Database Service (RDS) for running managed databases like PostgreSQL.

Don't worry! You don't have to understand the entire diagram all at once. We'll take it to step by step and go through each component one at a time until you have a complete understanding of the architecture. By the end of this blog, you will know exactly what Amazon Web Services (AWS) three-tier architecture looks like and how it works. ๐Ÿš€


Components of the Architecture ๐Ÿค–

Let's discuss the components of the architecture, starting with the web server, application server, database server, Auto Scaling Group (ASG), and Application Load Balancer (ALB).

The three-tier architecture is broken down into the following components:

  • Web Server: The web server is responsible for handling all incoming requests from the client and proxying those requests to the application server using a reverse proxy. In this case, we use an Nginx web server. This belongs to the presentation tier.

  • Application Server: The application server receives the requests processed by the web server, retrieves data from the database server and returns the necessary results back to the web server. It is equipped with a Java Servlet and we are using Apache Tomcat in our example.

  • Database Server: The database server is responsible for all the storage and organization of data in our application. We are using PostgreSQL as our database server.

  • Amazon EC2 Instances: Both our web server and application servers are running on separate Amazon EC2 instances, which are virtual machines in the cloud that we can use to run applications.

  • Amazon RDS: Our database server is running on an Amazon RDS instance, which is a managed database service that makes it easier to set up, operate, and scale a database in the cloud.

  • Auto Scaling Group (ASG): An ASG allows users to set a desired number of instances. The group will then ensure that the proper number of instances are available at all times by adding or removing instances from the group based on current usage.

  • Application Load Balancer (ALB): An ALB is a component which redirects traffic to two or more instances. This ensures minimal latency and allows for better availability in the event of an instance failure.

Why do we need ALB and ASG?๐Ÿค” ALBs and ASGs are necessary components for creating a robust cloud infrastructure. They enable increased availability, scalability, reliability, and security of the architecture. ALBs enable improved performance by directing traffic to multiple servers and ASGs ensure that a viable number of instances are available and able to handle the load.

We have added an Application Load Balancer (ALB) in front of both our web server and application server and have also configured Auto-Scaling Groups (ASGs) to ensure that there is enough computing power available to keep up with the demand of the application.

The ALB distributes incoming traffic across the group of EC2 instances and the ASG ensures that the correct number of EC2 instances are provisioned so that at all times our application is performing optimally. ๐Ÿ“ˆ


Using Amazon EC2 and Amazon RDS ๐Ÿค”

Amazon EC2 and Amazon RDS allow users to quickly set up a robust cloud infrastructure with three-tier architecture.

The web tier is comprised of multiple Amazon Elastic Compute Cloud (EC2) instances in different availability zones (us-east-1a and us-east-1b) running an Nginx web server to receive incoming HTTP requests from the client.

The application tier also has multiple Amazon Elastic Compute Cloud (EC2) instances in different availability zones (us-east-1a and us-east-1b), with Apache Tomcat installed, which processes the requests and retrieves data from the database tier.

The database tier is an Amazon Relational Database Service (RDS) instance running PostgreSQL. An Application Load Balancer sits in front of both EC2 web and application instances, ensuring incoming requests are routed to the correct instance. For redundancy, both EC2 tiers are deployed using Auto Scaling Groups (ASG), which helps maintain availability and performance by enabling them to scale up or down and automatically replaced if an instance is unhealthy.

NOTE: The web server and application server are typically placed in private subnets which ensures their security within the AWS environment. The web server is exposed to the public using an Application Load Balancer endpoint, allowing it to accept requests from the public internet. This combination of EC2, RDS, ALB, and ASG allows for the creation of a secure, scalable, and highly available architecture. ๐Ÿ˜Ž

Tip: If you want to create an AWS resource with CloudFormation, search for its resource type (e.g. AWS::EC2::Instance) on Google and review its properties in either JSON or YAML format - we recommend YAML for this purpose.


Networking on AWS โœจ

The architecture consists of a VPC, with one public and three private subnets. The web server, an EC2 instance running Nginx is placed in the private subnet and is accessible only through the internet via an external Application Load Balancer (ALB). This ALB is responsible for forwarding the traffic received to the web server.

The application server, an EC2 instance running Apache Tomcat, and the database server, an RDS instance, are also placed in the private subnets, making them inaccessible from the internet. The RDS instances have a DB Subnet Group, composed of two private subnets to create redundancy within Availability Zones.

This architecture also includes a NAT Gateway to allow instances in the private subnet to access the internet when necessary, an Internet Gateway to establish communication between the instances in the VPC and the internet, and a route table for the public subnet to which routes are mapped to the Internet Gateway.

By using the resources mentioned above, we can ensure that all the components are securely ๐Ÿ” connected to build a robust cloud infrastructure.

Resources: 
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: MyVPC

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
          - Key: Name
            Value: MyInternetGateway

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.0.0/24
      VpcId: !Ref VPC
      MapPublicIpOnLaunch: true
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      Tags:
        - Key: Name
          Value: MyPublicSubnet

  PrivateSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: 10.0.1.0/24
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: MyPrivateSubnet1

  NATGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NATGatewayEIP.AllocationId
      SubnetId: !Ref PublicSubnet

  NATGatewayEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC

  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      GatewayId: !Ref InternetGateway
      DestinationCidrBlock: 0.0.0.0/0
      RouteTableId: !Ref PublicRouteTable

  PrivateRoute:
    Type: AWS::EC2::Route
    DependsOn: NATGateway
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NATGateway
      RouteTableId: !Ref PrivateRouteTable

  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet

  PrivateSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      SubnetId: !Ref PrivateSubnet

Security Groups and NACLs ๐Ÿ”

For security purposes, each instance should have its security group containing rules that allow or deny specific types of traffic from other instances in the VPC. The web server should have a security group with rules to allow incoming traffic from the ALB on port 80 (HTTP) and port 22 (SSH). The application server should have rules to allow traffic from the web server on port 8080, and port 22 (SSH) and to allow traffic from the database server on the default PostgreSQL port (5432). The security group for the database server should have rules to allow traffic only from the application server on the default PostgreSQL port (5432).

  WebServerSG:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: !Sub "${AWS::StackName}-http"
      GroupDescription: Security Group for WebServer
      VpcId: !Ref VPC
      SecurityGroupIngress: 
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Ref ExternalALBId
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0

  AppServerSG:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: !Sub "${AWS::StackName}-app"
      GroupDescription: Security Group for AppServer
      VpcId: !Ref VPC
      SecurityGroupIngress: 
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          SourceSecurityGroupId: !Ref InternalALBId
        - IpProtocol: tcp
          FromPort: 5432
          ToPort: 5432
          SourceSecurityGroupId: !Ref DatabaseSG

  DatabaseSG:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupName: !Sub "${AWS::StackName}-db"
      GroupDescription: Security Group for DatabaseServer
      VpcId: !Ref VPC
      SecurityGroupIngress: 
        - IpProtocol: tcp
          FromPort: 5432
          ToPort: 5432
          SourceSecurityGroupId: !Ref AppServerSG

  DBSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupName : !Sub "${AWS::StackName}-dbgroup"
      DBSubnetGroupDescription: A group of subnets for db cluster
      SubnetIds:
        - !Ref PrivateSubnet1
        - !Ref PrivateSubnet2

An Amazon NACL (Network Access Control Lists) is a virtual firewall that enables you to control inbound and outbound traffic for virtual private cloud subnets in your AWS environment. A network ACL works similarly to a security group but applies to all of the instances in a subnet instead of individual instances. You can create rules to allow or deny traffic to and from your instances, and also apply rules to specific IP addresses and ranges on either the inbound or outbound side. By creating an NACL resource in CloudFormation or YAML format, you will be able to define the rules to be applied to the instances in the different subnets.

Resources:
  Nacl:
    Type: AWS::EC2::NetworkAcl
    Properties: 
      VpcId: !Ref VPCID
      SubnetIds: 
        - !Ref PrivateSubnet1
        - !Ref PrivateSubnet2 
        - !Ref PrivateSubnet3
      Tags:
        - Key: Name
          Value: MyWebSecurityGroup
      # add some rules for the NACL
      # This is an entry of Network Access Control (NACL). It tells     to deny the inbound TCP traffic from any IP address on port 0.0.0.0/0. The egress parameter determines if the rule is applied to inbound or outbound traffic.
      NetworkAclEntries: 
        - IpProtocol: 6 # for TCP
          RuleAction: deny
          RuleNumber: 100
          Egress: 'false' # the rule is applied to ingress traffic
          CidrBlock: 0.0.0.0/0

Conclusion ๐Ÿ’ก

Congratulations!๐ŸŽ‰ You have reached the end of this deep dive into designing a secure, robust, three-tier architecture on AWS VPC. You have learned about the different components of a three-tier architecture and how these result in a secure, resilient cloud structure. You also understand how to properly configure the Amazon EC2 instances, ELBs, SGs and NACLs necessary for a successful deployment. With your newfound understanding, you can now confidently build and deploy scalable and reliable web applications. Hope you learned something new.

Cheers!โœŒ๏ธ


ย