VPC with servers in private subnets and NAT in AWS

Sourabh AswalSourabh Aswal
2 min read

In this blog, we'll walk through setting up a secure and scalable infrastructure on AWS using VPC, private/public subnets, NAT gateways, Auto Scaling Groups, and an Application Load Balancer. We'll deploy a Node.js app in private EC2 instances using Docker and expose it securely using an ALB.

We'll use my Docker image: sourabhaswal98/nodejs-currency-app
GitHub Repo: nodejs-currency-converter

Step 1: Create a VPC with Subnets and NAT Gateways

  • Create a VPC with a CIDR block (e.g., 10.0.0.0/16).

  • Inside the VPC, create:

    • 2 Public Subnets (e.g., 10.0.1.0/24, 10.0.2.0/24,)

    • 2 Private Subnets (e.g., 10.0.101.0/24, 10.0.102.0/24)

  • Create 1 NAT Gateway per Availability Zone (attach them to public subnets).

  • Update the route tables:

    • Public subnets: route to Internet Gateway

    • Private subnets: route to NAT Gateway


๐Ÿ” Step 2: Create Security Group

Create a security group with the following rules:

  • Inbound:

    • TCP 22 (SSH)

    • TCP 80 (HTTP)

    • TCP 443 (HTTPS)

    • TCP 3000 (App port)

  • Outbound: Allow all


๐Ÿงฉ Step 3: Create Launch Template

  • Create a Launch Template:

    • Amazon Linux 2 or Ubuntu AMI

    • Use the security group from step 2

    • Add user-data if needed (weโ€™ll do that on the bastion)


๐Ÿ“ˆ Step 4: Create Auto Scaling Group

  • Use the launch template to create an Auto Scaling Group

  • Attach it to the private subnets

  • Set desired capacity (e.g., 2 instances)


๐Ÿ” Step 5: Create Bastion Host (Jump Box)

  • Launch a Bastion Host in one of the public subnets

  • Use the same security group

  • SSH into the Bastion and install Docker:

  • Run the Dockerized Node.js app:


๐ŸŽฏ Step 6: Create Target Group

  • Create a Target Group (instance type, HTTP, port 3000)

  • Register the EC2 instances (from private subnets/ASG) into the target group


๐ŸŒ Step 7: Create Application Load Balancer

  • Create an ALB in public subnets

  • Attach the target group

  • Configure listeners:

    • HTTP (port 80) โ†’ Forward to target group

Once done, access your app using the Load Balancer DNS.
You should see your currency converter Node.js app running live

0
Subscribe to my newsletter

Read articles from Sourabh Aswal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sourabh Aswal
Sourabh Aswal