Why this matters: This architecture is used by companies for applications requiring strict network isolation, PCI compliance or multi-tier security. It demonstrates production-grade cloud infrastructure design.
This project demonstrates the design and implementation of a production-style AWS VPC with public, private and database tiers, complete with bastion access, NAT gateway, custom Security Groups, custom Network ACLs and full connectivity testing.
This project was built completely hands-on using the AWS console and tested end-to-end using SSH, ProxyJump and curl commands.
This project implements a 3-tier VPC architecture commonly used in production environments:
- Public Subnets → bastion host, NAT gateway, future load balancer
- Private Subnets → application EC2 instances
- Database Subnets → isolated DB tier
- NAT Gateway → secure outbound internet for private instances
- Internet Gateway → inbound/outbound for public subnets
- Custom Security Groups & NACLs
- SSH bastion flow & NAT Gateway testing
This is the exact type of network design required for modern cloud applications.
AWS Services:
- VPC (subnets, route tables, NACLs)
- EC2 (Amazon Linux 2)
- Internet Gateway
- NAT Gateway
- Security Groups
Tools & Protocols:
- SSH / ProxyJump
- Bash / curl
- AWS Console
.
├── diagram/
│ └── vpc-architecture.jpeg
├── screenshots/
│ ├── public-rt-subnet-association.jpeg
│ ├── app-nacl-inbound.jpeg
│ ├── app-nacl-outbound.jpeg
│ ├── db-nacl-inbound.jpeg
│ ├── db-nacl-outbound.jpeg
│ ├── ssh-failure.jpeg
│ ├── ssh-success.jpeg
│ ├── private-ec2-access.jpeg
│ └── curl-nat-test.jpeg
└── README.md
- AWS Account with appropriate IAM permissions
- SSH key pair created in eu-west-2 region
- Basic understanding of VPC, subnets and routing concepts
- AWS CLI or Console access
VPC CIDR: 10.0.0.0/16
AZs Used: eu-west-2a and eu-west-2b
10.0.1.0/24(eu-west-2a)10.0.2.0/24(eu-west-2b)
10.0.11.0/24(eu-west-2a)10.0.12.0/24(eu-west-2b)
10.0.21.0/24(eu-west-2a)10.0.22.0/24(eu-west-2b)
📌 This shows both public subnets correctly associated with the Public Route Table.
0.0.0.0/0→ Internet Gateway
0.0.0.0/0→ NAT Gateway
This ensures the private tier can reach the internet securely without exposing instances publicly.
- A dedicated Internet Gateway was created and attached to the VPC
- A NAT Gateway was deployed inside Public Subnet 1 with an Elastic IP
This enables application servers to download updates, reach package repositories and access APIs securely.
- Allow 80/443 from anywhere
- Allow 22 only from my IP
- Allow app port 8080 ONLY from Web-SG
- Allow SSH ONLY from Web-SG
- Allow MySQL 3306 ONLY from App-SG
This ensures traffic flows strictly tier → tier, never bypassing layers.
Custom NACLs were created for:
These enforce subnet-level security:
- Only app subnets can reach DB subnet
- Only necessary ports allowed
- All other inbound traffic denied
A bastion host was created in a public subnet.
This failure was due to strict NACL rules — part of the learning process.
Once NACL and SG rules were corrected, SSH access worked perfectly.
# Template - replace with your actual IPs
ssh -i linux-project-key.pem \
-J ec2-user@BASTION_PUBLIC_IP \
ec2-user@PRIVATE_INSTANCE_IP
# Example
ssh -i linux-project-key.pem \
-J ec2-user@18.130.XXX.XXX \
ec2-user@10.0.11.244This validates the bastion → private flow is functioning securely.
Inside the private EC2 instance:
curl -I https://amazon.com
curl -I https://checkip.amazonaws.com📌 This confirms outbound internet works from a private subnet using the NAT Gateway.
✅ Public subnet → Internet (via IGW)
✅ Private subnet → Internet (via NAT Gateway)
✅ Bastion → App EC2 via SSH
✅ App EC2 → DB subnets allowed
✅ Tier isolation enforced via SGs & NACLs
✅ All traffic flows correct and secure
This matches real-world production architecture.
- Cause: Incorrect inbound rules
- Fix: Allowed SSH from my public IP only
- Cause: Private subnet accidentally associated with wrong route table
- Fix: Re-associated subnet to Private-RT
- Cause: Missing ProxyJump configuration
- Fix: Used correct
-Jflag and ensured SG/NACL allowed traffic
These demonstrate real-world problem-solving and understanding of AWS networking.
- NAT Gateway: Charges per hour + data transfer costs
- EC2 instances: t2.micro eligible for free tier
- Elastic IP: Free when attached, charges when idle
- Main cost driver: NAT Gateway if left running continuously
💡 Tip: Stop EC2 instances and delete NAT Gateway when not in use to minimize costs. Always check AWS pricing calculator for your specific region.
⚠️ Never commit.pemfiles to Git- Bastion SSH limited to your IP only
- Consider AWS Systems Manager Session Manager for production (removes SSH key management)
- Regularly rotate SSH keys and review Security Group rules
- Enable VPC Flow Logs for network traffic monitoring
Planned improvements:
- Add an Application Load Balancer
- Configure Auto Scaling Group
- Add RDS Multi-AZ database
- Use Systems Manager Session Manager (remove SSH entirely)
- Add CloudWatch Dashboards
- Use Terraform or CloudFormation for end-to-end IaC
- Implement VPC Flow Logs for monitoring
- Add AWS WAF for web application firewall
- Designing multi-tier VPC architectures for production environments
- Implementing defense-in-depth with Security Groups AND NACLs
- Troubleshooting network connectivity issues systematically
- Using bastion hosts and ProxyJump for secure access
- Understanding the difference between stateful (SG) and stateless (NACL) firewalls
- NAT Gateway configuration for private subnet internet access
aws vpc cloud-security cloud-architecture nat-gateway bastion-host nacl security-groups linux networking
If you have questions or suggestions, feel free to open an issue or reach out!
This project is for educational purposes. Feel free to use and modify as needed.
Built with ☁️ by Usman Ul-Haq









