This project demonstrates how to design and deploy a secure, production-style AWS Virtual Private Cloud (VPC) using Terraform. The infrastructure is fully defined as Infrastructure as Code (IaC), enabling repeatable, version-controlled, and automated deployments.
The environment follows AWS networking best practices by implementing a multi-tier architecture with dedicated public, private, and data subnets distributed across multiple Availability Zones. Secure routing, network segmentation, centralized logging, and private AWS service connectivity are incorporated to improve security, scalability, and maintainability.
This project was built as part of my Cloud Security Portfolio to demonstrate practical experience with AWS networking, Terraform, and secure infrastructure design.
- Infrastructure provisioned entirely using Terraform
- Production-style AWS VPC architecture
- Multi-AZ deployment
- Public, Private, and Data subnet segmentation
- Internet Gateway and NAT Gateway configuration
- Custom Route Tables
- Security Groups implementing least privilege
- Dedicated Network ACLs
- Amazon S3 Gateway Endpoint
- VPC Flow Logs integrated with CloudWatch Logs
- Reusable Terraform configuration with variables and outputs
Internet
│
Internet Gateway
│
┌────────────────────┐
│ Production VPC │
│ 10.0.0.0/16 │
└────────────────────┘
│ │
Public Subnets Private Subnets
│ │
NAT Gateway Application Tier
│
Internet Access
Data Subnets
│
Database Tier
S3 Gateway Endpoint
│
Amazon S3
VPC Flow Logs
- VPC CIDR:
10.0.0.0/16 - Availability Zones: 2
- Public Subnets: 2
- Private Subnets: 2
- Data Subnets: 2
- Internet Gateway: 1
- NAT Gateway: 1
- Elastic IP: 1
- Route Tables: 3
- Security Groups: 4
- Network ACLs: 3
- S3 Gateway Endpoint: 1
- VPC Flow Logs: Enabled
| Category | Technology |
|---|---|
| Cloud Platform | AWS |
| Infrastructure as Code | Terraform |
| Networking | Amazon VPC |
| Routing | Internet Gateway, NAT Gateway |
| Security | Security Groups, Network ACLs |
| Monitoring | CloudWatch Logs |
| Logging | VPC Flow Logs |
| Connectivity | Amazon S3 Gateway Endpoint |
| Version Control | Git & GitHub |
vpc-infrastructure-as-code/
│
├── terraform/
│ ├── versions.tf
│ ├── main.tf
│ ├── variables.tf
│ ├── terraform.tfvars.example
│ ├── vpc.tf
│ ├── routing.tf
│ ├── nat.tf
│ ├── security_group.tf
│ ├── nacls.tf
│ ├── endpoints.tf
│ ├── flow_logs.tf
│ ├── outputs.tf
│ ├── .gitignore
│ └── README.md
│
├── diagrams/
│ └── architecture.png
│
├── screenshots/
│
└── README.md
| File | Purpose |
|---|---|
versions.tf |
Defines the required Terraform and AWS Provider versions. |
main.tf |
Configures the AWS provider and common settings. |
variables.tf |
Declares reusable input variables for the infrastructure. |
terraform.tfvars.example |
Sample variable values for deployment. |
vpc.tf |
Creates the VPC and six subnets across two Availability Zones. |
routing.tf |
Configures the Internet Gateway, Route Tables, and subnet associations. |
nat.tf |
Provisions the Elastic IP and NAT Gateway for outbound internet access from private subnets. |
security_group.tf |
Defines Security Groups following the principle of least privilege. |
nacls.tf |
Creates dedicated Network ACLs for public, private, and data subnets. |
endpoints.tf |
Configures the Amazon S3 Gateway VPC Endpoint. |
flow_logs.tf |
Enables VPC Flow Logs and CloudWatch logging. |
outputs.tf |
Exposes useful resource IDs after deployment. |
A dedicated VPC was created using the CIDR block:
10.0.0.0/16
This provides approximately 65,000 private IPv4 addresses and acts as the network boundary for all deployed resources.
The infrastructure follows a three-tier architecture distributed across two Availability Zones.
| Tier | CIDR Block | Purpose |
|---|---|---|
| Public Subnet A | 10.0.1.0/24 |
Internet-facing resources |
| Public Subnet B | 10.0.2.0/24 |
High availability |
| Private Subnet A | 10.0.10.0/24 |
Application layer |
| Private Subnet B | 10.0.20.0/24 |
High availability |
| Data Subnet A | 10.0.100.0/24 |
Database tier |
| Data Subnet B | 10.0.200.0/24 |
High availability |
This design provides network segmentation between public-facing resources, application workloads, and the data layer.
The public subnets are connected to the internet through an Internet Gateway.
Private subnets do not have direct internet access. Instead, outbound internet traffic is routed through a NAT Gateway deployed in a public subnet.
This architecture allows private workloads to download updates or access AWS services while preventing unsolicited inbound internet traffic.
Three dedicated Route Tables are implemented:
| Route Table | Purpose |
|---|---|
| Public | Routes internet-bound traffic through the Internet Gateway |
| Private | Routes outbound traffic through the NAT Gateway |
| Data | Restricts direct internet access for the database tier |
Each subnet is explicitly associated with the appropriate Route Table to maintain clear separation between network tiers.
Security was a primary design consideration throughout this project. Multiple layers of protection were implemented using AWS networking and security services to follow the principle of defense in depth.
Security Groups provide stateful, instance-level firewall protection by controlling inbound and outbound traffic.
Purpose
Provides secure administrative SSH access.
Inbound Rules
| Protocol | Port | Source |
|---|---|---|
| SSH | 22 | Administrator Public IP |
Outbound Rules
- Allow all outbound traffic
Purpose
Protects the application layer while allowing controlled access.
Inbound Rules
| Protocol | Port | Source |
|---|---|---|
| HTTP | 80 | Internet (0.0.0.0/0) |
| SSH | 22 | Bastion Security Group |
Outbound Rules
- Allow all outbound traffic
Purpose
Restricts database access to the application tier only.
Inbound Rules
| Protocol | Port | Source |
|---|---|---|
| MySQL | 3306 | Application Security Group |
Outbound Rules
- Allow all outbound traffic
Purpose
Reserved for future management or monitoring resources.
Inbound Rules
None
Outbound Rules
- Allow all outbound traffic
Dedicated Network ACLs provide stateless subnet-level filtering in addition to Security Groups.
Separate NACLs were created for:
- Public Subnets
- Private Subnets
- Data Subnets
This layered approach improves security by enforcing traffic controls at both the subnet and instance levels.
The VPC is divided into three logical network tiers.
| Tier | Purpose |
|---|---|
| Public | Internet-facing resources and NAT Gateway |
| Private | Internal application workloads |
| Data | Database resources with no direct internet route |
Network segmentation limits lateral movement and helps isolate workloads with different security requirements.
An Amazon S3 Gateway Endpoint is configured to allow private communication with Amazon S3 over the AWS network.
- No public internet traversal
- Reduced NAT Gateway usage
- Lower operational costs
- Improved security posture
- Better performance for S3 access
VPC Flow Logs are enabled to capture network traffic metadata for monitoring and troubleshooting.
Flow Logs are delivered to Amazon CloudWatch Logs using a dedicated IAM role.
This enables:
- Network traffic visibility
- Security investigations
- Operational troubleshooting
- Audit support
This project incorporates several AWS security best practices, including:
- Infrastructure provisioned using Infrastructure as Code (IaC)
- Multi-AZ architecture for improved availability
- Public, private, and data subnet isolation
- Principle of least privilege using Security Groups
- Defense in depth with Security Groups and Network ACLs
- Controlled outbound internet access through a NAT Gateway
- Private connectivity to Amazon S3 using a Gateway Endpoint
- Centralized logging with VPC Flow Logs and CloudWatch Logs
- Reusable and version-controlled Terraform configuration
The infrastructure can be deployed using the following Terraform workflow.
terraform initterraform fmtterraform validateterraform planterraform applyterraform destroy