VPC with public-private subnet in production

Building a Secure VPC: Public and Private Subnets in Production

ยท

9 min read

What we do:

In this project, we'll walk through the process of creating a Virtual Private Cloud (VPC) suitable for hosting servers in a production environment.

We'll focus on enhancing resiliency by deploying servers across two Availability Zones, utilizing an Auto Scaling group and an Application Load Balancer. Additionally, we'll ensure security by placing servers in private subnets and enabling connectivity to the internet via a NAT gateway. For extra reliability, we'll put the NAT gateway in both Availability Zones.


Architecture Diagram:

If you look at the architecture diagram here, you'll see a well-structured setup. At its core is the Virtual Private Cloud (VPC). Inside the private subnet, we've deployed our applications. Meanwhile, in the public subnet, we've placed our load balancer and NAT Gateway.

Users access our applications through the internet gateway, reaching the load balancer first. From there, requests are directed to the applications in the private subnet. This setup ensures a secure and efficient flow of traffic.

This architecture provides a robust foundation for hosting servers in a production environment, with considerations for resiliency and security at every step.


Overview:-

  • The VPC has public subnets and private subnets in two Availability Zones.

  • Each public subnet contains a NAT gateway and a load balancer node.

  • The servers run in the private subnets, are launched and terminated by using an Auto Scaling group, and receive trafic from the load balancer.

  • The servers can connect to the intemet by using the NAT gateway.


Prerequisites

  • Auto Scaling Group: Required for dynamically adjusting server capacity based on demand.

  • Load Balancer: Necessary for distributing incoming traffic across multiple servers for improved reliability and scalability.

  • Target Group: Defines the destination for traffic forwarded by the load balancer, specifying which servers to route requests to.

  • Bastion Host or Jump Server: Provides a secure gateway for accessing and managing servers in private subnets.


Implementation:

Creating VPC

  1. Sign in to AWS Console: Go to the AWS Management Console and sign in to your AWS account.

  2. Navigate to VPC Dashboard: In the top search bar, type "VPC" and select "VPC" from the suggestions. This will take you to the VPC Dashboard.

  3. Start VPC Creation: On the VPC Dashboard, click on the "Create VPC" button to initiate the VPC creation process.

  4. Choose VPC Configuration: Select the option for "VPC with Public and Private Subnets" to create a VPC with pre-configured public and private subnets across multiple availability zones.

  5. Configure VPC Details:

    • Enter a name for your VPC (e.g., "AWS prod example").

    • Keep the IPv4 CIDR block as default or modify as needed.

    • Leave the IPv6 CIDR block as "No IPv6 CIDR block".

    • Choose the number of availability zones (e.g., 2).

    • Specify the number of public and private subnets (e.g., 2 each).

    • Decide on the number of NAT gateways (e.g., 1 per availability zone).

  6. Review and Create: Review the VPC configuration details. Ensure that the diagram preview reflects the desired architecture with public and private subnets across multiple availability zones.

  7. Create VPC: Click on the "Create VPC" button to create the VPC with the specified configuration.

  8. Confirmation: Once the VPC creation process is complete, you'll see a confirmation message indicating that the VPC has been successfully created.

Creating auto-scaling group:

  1. Search for EC2: In the AWS Management Console, go to the search bar and type "EC2". Select the EC2 option from the suggestions.

  2. Navigate to Auto Scaling Groups: Scroll down in the EC2 dashboard until you find the "Auto Scaling Groups" option. Click on it.

  3. Create Auto Scaling Group: On the Auto Scaling Groups page, click on the "Create Auto Scaling Group" button.

  4. Select Launch Template: Auto Scaling Groups cannot be created directly; you'll need to use a Launch Template. Click on the link provided to create or select a Launch Template.

  5. Create Launch Template: Create a new Launch Template by providing a name and basic configuration details such as name, AMI, instance type, and security group.

  6. Configure Security Group: Create a new security group or select an existing one. Add inbound rules to allow traffic to your instances (e.g., SSH and application ports) and click create launch template.

    { Again Navigate to Auto Scaling Groups then do as follow : }

  7. Choose Launch template:-

  8. Choose VPC and Subnets: Select the VPC and subnets where you want your instances to be launched. Choose private subnets for instances in this context.

  9. Set Capacity and Scaling Options: Define the desired capacity (number of instances), minimum and maximum sizes, and scaling policies if needed.

  10. Review and Create: Review the configuration details and then create the Auto Scaling Group.


[NOTE:- To install applications on the servers, we need to access them. However, the instances don't have public IP addresses for security reasons. To address this, we'll create a Bastion Hostโ€”a mediator between the private subnet and external access. This Bastion Host will enable secure access to the private subnet, allowing us to install applications on the servers. ]

Create Bastion Host or Jump Server:-

  1. Access Instances: Navigate to the EC2 dashboard and click on "Instances".

  2. Create Bastion Host: Launch a new instance for the Bastion Host with the desired configuration (e.g., Ubuntu image, T2 micro instance type).

  3. Configure Security Group: Ensure the Bastion Host's security group allows SSH access (Port 22) for connecting to other instances.

  4. Network Settings: Verify that the Bastion Host is created in the same VPC as the servers to be accessed.

  5. Auto Assign Public IP: Enable auto-assignment of a public IP address for the Bastion Host.

    NOTE :- Make sure choose the public subnet

  6. Launch Instance: Review the configuration and launch the Bastion Host instance.


Note:- Once the Bastion Host instance is launched, we'll SSH into it from my personal laptop. From there, we'll SSH into the private subnet. However, to SSH into the private subnet, we'll need the key pair that is present on my laptop.

Login to the private-instance through bastion-host-server :

scp -i /path/to/your/private/key.pem /path/to/local/file username@bastion_host_public_ip:/path/to/destination

ssh -i "name-of-pem-key" ubuntu@ec2-ip-address-of-your-ec2.compute-1.amazonaws.com

  1. Logged into Private Instance: logging to the private instance through its private-IP using the bastion host where we already copy the pem file of this private instance.

    copy the private IP:

    now ssh to the private instance using command :

     ssh -i "pem_file_location" user_name@private_ip
    

  2. Created Simple HTML Page: I created a basic HTML page named "index.html" to demonstrate hosting a web page.

     <!DOCTYPE html>
     <html>
     <body>
    
     <h1>My First Heading </h1>
     <p>My first paragraph.</p>
    
     </body>
     </html>
    

  3. Ran Python Server: I ran a Python HTTP server on Port 8000 within the EC2 instance, serving the "index.html" page.

     python3 -m http.sever 8000
    


Load balancer creation ;

  1. Navigate to EC2 Dashboard: Log in to your AWS Management Console and navigate to the EC2 dashboard.

  2. Go to Load Balancers: In the EC2 dashboard, locate the "Load Balancers" option in the navigation pane and click on it.

  3. Create Load Balancer: Click on the "Create Load Balancer" button.

  4. Choose Load Balancer Type: Select the type of load balancer you want to create. For this example, let's choose the "Application Load Balancer" as it operates at Layer 7 and can handle HTTP and HTTPS traffic.

  5. Configure Load Balancer Settings:

    • Provide a name for your load balancer.

    • Choose "Internet-facing" if your load balancer will be accessible from the internet.

    • Select the VPC where you want to deploy the load balancer.

    • Specify the subnets where you want to place the load balancer. Ensure these subnets are public subnets.

  6. Assign Security Settings:

    • Choose an existing security group or create a new one for your load balancer.

    • Ensure that the security group allows inbound traffic on the necessary ports (e.g., Port 80 for HTTP).

  7. Configure Routing:

    • Set up listeners for your load balancer. For HTTP traffic, set up a listener on Port 8000. For HTTPS traffic, set up a listener on Port 443.

    • Define the target group associated with the listener. This determines where the load balancer sends incoming traffic.

  8. Create Target Group:

    • If you haven't already created a target group, you can do so during load balancer creation.

    • Define the target group settings, including health checks and target types (e.g., instances, IP addresses, Lambda functions).

  9. Configure Health Checks:

    • Set up health checks to monitor the health of your targets (e.g., instances).

    • Define the protocol, port, and health check path for the health checks.

  10. Add Targets:

  • Specify the targets (e.g., EC2 instances) that should receive traffic from the load balancer.

  • Ensure that the targets are registered with the target group and pass the health checks.

    add this target group to the load balancer configuration

  1. Review and Create: Review all the configurations you've made for the load balancer and its associated settings. Once you're satisfied, click on the "Create" button.

  2. Wait for Provisioning: AWS will provision your load balancer, which may take a few minutes. Once the load balancer is provisioned and in the "Active" state, you can start using it to distribute traffic to your targets.


Access the website :

  1. copy the DNS address of the load balancer:

  2. paste on the browser


That's it! You've successfully created a production level VPC in AWS.


Connect with me:)

Thank you for diving into this blog with me! I trust you found the information both helpful and enlightening. To stay updated on the latest in DevOps ๐Ÿš€, make sure to follow me. Remember, staying informed means staying ahead in the dynamic world of DevOps!

Feel free to connect with me on:

LinkedIn

Twitter

GitHub

For more updates and engaging discussions on DevOps, let's connect! ๐Ÿš€ #DevOpsCommunity

ย