This project provisions a production-grade AWS infrastructure using Terraform with a modular and scalable architecture.
We built this infrastructure step-by-step like a real DevOps workflow:
- Created a custom VPC
- Public and Private subnets across multiple AZs
- Internet Gateway for public access
- Route tables for proper traffic routing
-
Separate security groups for:
- ALB
- EC2
-
Implemented:
- SSH restricted to developer IP
- HTTP open only where required
- EC2 accepts traffic only from ALB
- Launched EC2 instance using Terraform
- Installed Nginx using
user_data - Configured SSH access with key pair
- Output public IP for testing
- Application Load Balancer in public subnets
- Target Group with health checks
- Listener routing HTTP → EC2
- Attached EC2 instance to ALB
-
Removed public access from EC2
-
Introduced ALB as the only entry point
-
Implemented SG-to-SG communication:
- ALB → EC2 only
- Added Elastic IP + NAT Gateway
- Enabled private EC2 instances to access internet
- Fixed issue where Nginx install failed without internet
- Modules should NOT be applied individually
- Use environment folders (
dev,prod) for execution - Use outputs to expose module data
- Use
${path.module}for file references
- Public subnet = Internet Gateway route
- Private subnet = NAT Gateway route
- No NAT = no outbound internet
502 Bad Gateway→ backend issue- Target Group unhealthy → app not responding
- SG dependency errors → resource still attached
- Key pair issues → must recreate EC2
Internet
↓
ALB (Public Subnet)
↓
EC2 (Private Subnet)
↓
NAT Gateway → Internet
shopshere-terraform/
├── modules/
│ ├── vpc/
│ ├── ec2/
│ ├── alb/
│ ├── security_group/
│
├── environments/
│ ├── dev/
│ ├── prod/
│
├── global/
│ ├── s3-backend/
│
├── provider.tf
├── variables.tf
├── outputs.tf
├── versions.tf
cd environments/devterraform initterraform planterraform apply- Access app via:
http://<ALB_DNS>
- EC2 is NOT publicly accessible (by design)
- NAT Gateway incurs cost 💸
- Do NOT expose EC2 publicly in production
- Always restrict SSH access
- Never hardcode secrets in Terraform
- Use AWS SSM Session Manager instead of SSH
- Add Auto Scaling Group
- Add HTTPS (ACM + Route53)
- Store secrets in AWS Secrets Manager
- CI/CD integration (GitHub Actions)
This project demonstrates a real-world production-ready AWS architecture using Terraform:
✔ Modular ✔ Secure ✔ Scalable ✔ Maintainable
💡 Built as a hands-on DevOps learning project