Skip to content
EgyKode
Guided lab

AWS VPC, Subnets, Gateways & Route Tables

47 minIntermediate

This creates billable resources. Run it in a dev environment and destroy it when you finish. Set a budget alarm first.

Success criteria

0 of 5

What you are building#

What is an AWS Virtual Private Cloud (VPC)?#

An AWS Virtual Private Cloud (VPC) is a logically isolated virtual network dedicated to your AWS account. It gives you complete control over your virtual networking environment, including selection of your own IP address range, creation of subnets, and configuration of route tables and network gateways.

Public vs. Private Subnet Topology Architecture#

Production enterprise cloud architecture mandates strict network boundary isolation:

  • Public Subnets: Connected directly to an Internet Gateway (IGW). Resources placed here (such as Application Load Balancers or Bastion Hosts) have public IP addresses and can receive inbound internet traffic.
  • Private Subnets: Isolated from direct public internet access. Compute workloads (such as EKS Worker Nodes and RDS PostgreSQL databases) reside here. Outbound internet access for software patching or container pulls is routed securely through a NAT Gateway located in a Public Subnet.
text
                                  AWS REGION (us-east-1)
                                  
  +-----------------------------------------------------------------------------------+
  |  VPC: nti-devops-vpc (CIDR: 10.0.0.0/16)                                          |
  |                                                                                   |
  |  +-----------------------------------------------------------------------------+  |
  |  |  PUBLIC SUBNETS (Connected to Internet Gateway)                             |  |
  |  |  +-------------------------------+     +---------------------------------+  |  |
  |  |  | Public Subnet A (us-east-1a)  |     | Public Subnet B (us-east-1b)    |  |  |
  |  |  | CIDR: 10.0.1.0/24             |     | CIDR: 10.0.2.0/24               |  |  |
  |  |  | - AWS Application LB (ALB)    |     | - NAT Gateway (Elastic IP)      |  |  |
  |  |  | - Jenkins EC2 (Public IP)     |     |                                 |  |  |
  |  |  +---------------+---------------+     +----------------+----------------+  |  |
  |  +------------------|--------------------------------------|-------------------+  |
  |                     | Routing                              | Outbound Egress      |
  |                     v                                      v                      |
  |  +-----------------------------------------------------------------------------+  |
  |  |  PRIVATE SUBNETS (No Public IPs — Routed via NAT Gateway)                   |  |
  |  |  +-------------------------------+     +---------------------------------+  |  |
  |  |  | Private Subnet A (us-east-1a) |     | Private Subnet B (us-east-1b)   |  |  |
  |  |  | CIDR: 10.0.10.0/24            |     | CIDR: 10.0.11.0/24              |  |  |
  |  |  | - EKS Managed Worker Nodes    |     | - RDS PostgreSQL Database       |  |  |
  |  |  +-------------------------------+     +---------------------------------+  |  |
  |  +-----------------------------------------------------------------------------+  |
  +-----------------------------------------------------------------------------------+

Steps#

Step 1: Initialize Terraform Working Directory#

Terminal
cd 01-Infrastructure-Terraform/Lab01-AWS-VPC-Networking
terraform init

What happens under the hood? Downloads the AWS Provider plugin (~> 5.0) into .terraform/ and initializes local backend state.

Step 2: Validate Syntax and Format#

Terminal
terraform fmt -check
terraform validate

Step 3: Generate Execution Plan#

Terminal
terraform plan -out=tfplan

Step 4: Apply Infrastructure Plan#

Terminal
terraform apply tfplan

Verify it worked#

Terminal
terraform output

Expected Terminal Output:

text
vpc_id              = "vpc-0a1b2c3d4e5f67890"
public_subnet_ids   = [
  "subnet-01111111111111111",
  "subnet-02222222222222222"
]
private_subnet_ids  = [
  "subnet-03333333333333333",
  "subnet-04444444444444444"
]
nat_gateway_ip      = "54.210.100.50"


Clean up#

Run this even if you did not finish. Everything above is destroyable, and an account full of half-built experiments is how a surprise bill starts.

DestructiveThis removes real resources. Check which environment you are in first.

Terminal
terraform destroy -auto-approve
# Verify the NAT Gateway is really gone — it is the only costly resource here:
aws ec2 describe-nat-gateways --filter Name=state,Values=available --query 'NatGateways[].NatGatewayId'
# Release any Elastic IP left behind (an unattached EIP is billed hourly):
aws ec2 describe-addresses --query 'Addresses[?AssociationId==`null`].[PublicIp,AllocationId]' --output table

Cost of this lab: Billable. The NAT Gateway is $0.045/hour ($32/month) plus $0.045/GB processed, and it bills whether or not traffic flows. The VPC, subnets and route tables are free. Destroy the NAT Gateway the moment you are done.

The concept behind it

Ready to try it without help?Do the challenge