AWS re/Start Lab · Networking

Build Your VPC and Launch a Web Server

This lab covers the full process of building a VPC from scratch, configuring subnets and route tables, creating a security group, and launching an EC2 instance with a User Data script to automatically deploy an Apache web server.

Lab Summary

Built a complete VPC architecture using the "VPC and more" wizard, then manually added additional subnets, configured a Security Group for HTTP access, and launched an EC2 web server. The original User Data script failed due to an AMI mismatch, which was resolved by adapting the script for Amazon Linux 2023.

VPC Foundation

Created Lab VPC (10.0.0.0/16) with the wizard, which automatically provisioned subnets, route tables, an Internet Gateway, and a NAT Gateway in a single Availability Zone.

Security & Subnets

Added Public Subnet 2 and Private Subnet 2 manually. Associated them with the correct route tables. Created Web Security Group allowing inbound HTTP from anywhere.

Deployment & Debugging

Launched an EC2 instance with User Data automation. The initial script failed due to an AMI version mismatch. After diagnosing via instance logs, a corrected script was applied successfully.

Step-by-Step Walkthrough

Documentation of the VPC construction process and the troubleshooting required to get the web server running.

01

Create the VPC using the wizard

  • Navigated to VPC > Create VPC and selected VPC and more.
  • Unchecked Auto-generate for name tags to name resources manually.
  • Configured: IPv4 CIDR 10.0.0.0/16, 1 Availability Zone, 1 public subnet, 1 private subnet, NAT Gateway in 1 AZ.
  • Named resources in the Preview pane: Lab VPC, Public Subnet 1, Private Subnet 1, Public Route Table, Private Route Table.
VPC NameLab VPC
IPv4 CIDR10.0.0.0/16
Public Subnet 110.0.0.0/24 (us-west-2a)
Private Subnet 110.0.1.0/24 (us-west-2a)
Internet GatewayAttached
NAT GatewayIn 1 AZ
02

Create additional subnets and associate route tables

  • Created Public Subnet 2 (CIDR: 10.0.2.0/24) with Availability Zone set to No preference.
  • Created Private Subnet 2 (CIDR: 10.0.3.0/24) with Availability Zone set to No preference.
  • Associated Public Subnet 2 with the Public Route Table (which has the 0.0.0.0/0 route to the Internet Gateway).
  • Associated Private Subnet 2 with the Private Route Table.
A subnet without an explicit route table association uses the VPC's main route table by default. To make Public Subnet 2 public, it must be explicitly associated with a route table that directs 0.0.0.0/0 traffic to the Internet Gateway.
03

Create the Web Security Group

  • Navigated to VPC > Security Groups and created a new group.
  • Named it Web Security Group with description "Enable HTTP access", attached to Lab VPC.
  • Added an Inbound Rule: Type HTTP, Source Anywhere IPv4 (0.0.0.0/0), Description: "Permit web requests".
04

Launch the web server instance

  • Created an EC2 instance named Web Server 1 with Amazon Linux AMI, instance type t3.micro, key pair vockey.
  • Network settings: VPC Lab VPC, Subnet Public Subnet 2, Auto-assign public IP Enabled, Security Group Web Security Group.
  • Pasted the guide's User Data script and launched.
Problem: After the instance passed the 2/2 status checks, the web page did not load via the Public IPv4 DNS, neither with HTTPS nor HTTP. Checking the instance log revealed that the User Data script had failed.
05

Debugging the User Data script failure

The instance log showed that the yum install -y httpd mysql php command failed because the AMI provided was Amazon Linux 2023, not Amazon Linux 2 as the guide assumed.

  • The mysql package does not exist in Amazon Linux 2023 repositories.
  • Because all three packages (httpd, mysql, php) were on a single yum install line, the failure of mysql caused httpd to not install either.
  • Without httpd, the directory /var/www/html/ was never created.
  • The unzip command failed because the target directory did not exist.
  • The web server never started → no page was served.

❌ Original Script (AL2)

#!/bin/bash
yum install -y httpd mysql php
wget https://aws-tc-[...]/lab-app.zip
unzip lab-app.zip -d /var/www/html/
chkconfig httpd on
service httpd start

✅ Fixed Script (AL2023)

#!/bin/bash
dnf install -y httpd
dnf install -y php
wget https://aws-tc-[...]/lab-app.zip
unzip lab-app.zip -d /var/www/html/
systemctl enable httpd
systemctl start httpd
Key changes: Replaced yum with dnf (the default package manager on AL2023), removed the mysql dependency (not needed for the lab app), installed packages on separate lines to prevent cascading failures, and used systemctl instead of chkconfig/service.
06

Successful deployment

A new instance was launched with the corrected script. After reviewing the instance log and confirming all commands executed successfully, the web application loaded correctly via the Public IPv4 address.

Key Learnings

Route Table Associations: Creating a subnet is not enough. New subnets must be explicitly associated with the correct route table (public or private) for them to inherit the expected internet behavior.
AMI Compatibility Matters: User Data scripts must match the target AMI. Amazon Linux 2023 uses dnf instead of yum and systemctl instead of service. Always verify which AMI the lab environment provides.
Defensive Scripting: Installing packages on separate lines prevents a single missing package from blocking the installation of all others. This is especially important for User Data scripts where there is no interactive session to catch errors.
Instance Logs for Debugging: When a User Data script fails silently, the EC2 instance log (Actions > Monitor and troubleshoot > Get system log) is the primary tool for diagnosing what went wrong during boot.