Launch, Connect, and Deploy on EC2
Launch an EC2 web server and understand every layer from hypervisor to HTTP.
Introduction
30 Second Summary
Every website you visit runs on a server somewhere. Cloud computing lets you spin up one of those servers in minutes, but most tutorials treat the underlying infrastructure as a black box.
In this project, you will launch a Linux web server on AWS EC2, deploy a custom web page with Nginx, and build a deep understanding of what happens at every layer from hypervisor to HTTP response.
What You'll Build
You will launch a server, deploy a page, watch it fail because of a missing firewall rule, fix it, and then capture the whole thing as a reusable golden image you can clone in seconds.
By the end of this project, you'll have:
- A custom web page served by Nginx on EC2 that you can visit in your browser using the instance's public IP address.
- A working SSH connection from your Windows terminal into your remote Linux server, giving you full command-line control.
- A clear mental model of the complete packet journey from browser to Nginx, including Security Groups, ENIs, and the Linux kernel.
- Secret Mission: Create a custom AMI (golden image) from your configured instance and launch a second identical server from it with zero manual setup.
Are there any prerequisites?
You need an AWS account (Free Tier eligible) and a Windows machine with Windows Terminal.
Basic familiarity with Linux commands (sudo, systemctl) is helpful. You should also understand the basics of VPCs, subnets, Internet Gateways, and route tables.
Before We Start
Before we dive in, let's lock in what you're about to build and why it matters.
Create Your SSH Key Pair
Your EC2 instance needs a way to verify your identity without a password. SSH key pairs solve this using asymmetric cryptography.
The public key lives on the server while your private key stays on your machine. A mathematical relationship between the two halves proves you are who you claim to be.
In this step, get ready to:
- Create an SSH key pair in the AWS Console.
- Secure the private key file on your Windows machine.
- Verify your SSH client is available.
Create a key pair in the EC2 Console
AWS needs the public half of a key pair so it can place it on your instance during launch. You create the pair in the EC2 Console, and AWS gives you back the private half as a .pem file.
- Sign in to the AWS Management Console at https://console.aws.amazon.com
- In the search bar at the top, type EC2 and select EC2 from the results.
- In the left sidebar, scroll down to the Network & Security section.
- Click Key Pairs.
- Click Create key pair in the top right.
- Enter ec2-first-principles in the Name field.
- For Key pair type, select RSA.
- For Private key file format, select .pem.
- Click Create key pair.
Your browser automatically downloads the ec2-first-principles.pem file to your Downloads folder.
What is a key pair?
A key pair is two mathematically linked files. The public key can be shared freely. The private key must stay secret.
When you SSH into your instance, the server challenges your client using the public key. Only your private key can answer correctly. This proves your identity without ever sending a password over the network.
Why RSA and .pem?
RSA is a widely supported encryption algorithm that works with all SSH clients. The .pem format is the standard OpenSSH-compatible format that Windows Terminal's SSH client expects.
Secure the key file on your Windows machine
Your private key is currently sitting in your Downloads folder where any application could read it. The SSH client will refuse to use a key file that has overly broad permissions.
- Press the Windows key to open your search bar.
- Type Windows Terminal and press Enter to open it.
- Create a .ssh directory and move the key file into it by running these commands:
mkdir $HOME\.ssh -Force
Move-Item $HOME\Downloads\ec2-first-principles.pem $HOME\.ssh\ec2-first-principles.pem
What do these commands do?
- mkdir $HOME\.ssh -Force creates the .ssh folder in your user profile directory. The -Force flag means it won't error if the folder already exists.
- Move-Item relocates the .pem file from Downloads into your new .ssh directory.
- Lock down the file permissions so only your user account can read it by running these commands:
icacls $HOME\.ssh\ec2-first-principles.pem /inheritance:r
icacls $HOME\.ssh\ec2-first-principles.pem /grant:r "$($env:USERNAME):(R)"
What do these commands do?
- /inheritance:r removes all inherited permissions from the file. This strips away the default access that other users and groups had.
- /grant:r replaces the permissions with a single explicit rule. Only your Windows username gets (R) (read-only) access.
- Confirm the file is in place by running:
ls $HOME\.ssh
You should see ec2-first-principles.pem listed in the output.
Don't see the file?
- Check that the file was actually downloaded. Go back to EC2 > Key Pairs and confirm ec2-first-principles appears in the list. If it does, the download succeeded. Check your Downloads folder manually.
- If you see an error about the file not being found in Downloads, the file may have been saved with a different name or to a different folder. Check your browser's download location in its settings.
- help me find my downloaded .pem key file
Verify SSH client availability
Windows 10 and later ship with OpenSSH client pre-installed. Before you try to connect to anything, confirm the ssh command is available.
- Before you run this, what do you expect to see if the SSH client is installed?
- Test that your SSH client is available by running:
ssh
✔️ I see usage output
You see a block of text starting with usage: ssh followed by a list of options and flags. This confirms the OpenSSH client is installed and ready. You're all set.
ⓧ Command not found
If you see an error indicating ssh is not recognized, you need to install the OpenSSH Client feature.
- Open Settings (press Windows key, type Settings).
- Click Apps, then Optional Features.
- Click Add a feature.
- Search for OpenSSH Client and click Install.
- Once installed, close and reopen Windows Terminal.
- Run ssh again. You should now see the usage output.
Still not working?
help me install the OpenSSH client on Windows
Your key pair is created, secured, and your SSH client is confirmed working. Next up, you'll use this key to launch your first EC2 instance with full understanding of what every configuration choice represents at the hardware level.
Launch Your EC2 Instance
Your SSH key pair is ready and secured on your machine. Now it's time to launch the virtual machine it will authenticate you into.
This is the conceptually heaviest step in the project. Before you click Launch instance, you need to understand what an EC2 instance actually is: a virtual machine running on physical hardware via the Nitro System. Every configuration choice you make maps directly to a physical resource in an AWS data center.
In this step, get ready to:
- Understand what virtualization, AMIs, instance types, and EBS volumes represent at the engineering level.
- Configure and launch an EC2 instance with the correct AMI, instance type, key pair, and security group.
- Verify the instance reaches Running state with a public IP address assigned.
Understand what you are about to create, then launch
You are about to select an AMI (the disk image containing your OS), an instance type (the slice of physical hardware allocated to you), and storage (a network-attached EBS volume). Each choice creates something real on a physical server.
What is an EC2 instance?
An EC2 instance is a virtual machine running on a physical server in an AWS data center. The physical server uses the Nitro System to partition its CPU, memory, and I/O across multiple isolated VMs. Each VM operates as if it has its own dedicated hardware.
The Nitro System has three components: Nitro Cards handle I/O virtualization (network and storage), the Nitro Security Chip provides a hardware root of trust, and the Nitro Hypervisor is a minimal KVM-based layer that partitions CPU and memory. Unlike traditional hypervisors, the Nitro Hypervisor has no shell, no file system, and no network stack. It does one job: divide physical resources between VMs.
- In the EC2 console, click Launch instance from the dashboard.
- Under Name and tags, enter web-server-first-principles in the Name field.
What is an AMI?
An AMI (Amazon Machine Image) is a template your instance boots from. It contains a snapshot of a root volume (the OS and any pre-installed software), a block device mapping (which volumes to attach), and a boot mode configuration.
When you launch an instance, EC2 creates a fresh EBS volume from the AMI's snapshot and attaches it as your root drive. Amazon Linux 2023 is a lightweight, security-focused OS built for EC2.
- Under Application and OS Images (Amazon Machine Image), click Quick Start.
- Select Amazon Linux as the operating system.
- From the Amazon Machine Image (AMI) dropdown, confirm Amazon Linux 2023 AMI is selected (marked Free tier eligible).
What does t3.micro mean at the hardware level?
The instance type defines the slice of physical hardware your VM receives. t3.micro gives you 2 vCPUs (threads on an Intel Xeon Scalable processor), 1 GiB of memory, and a 10% baseline CPU allocation per vCPU.
The T3 family runs on Nitro v2 hardware with burstable CPU. You get a steady 10% of each CPU thread, plus credits that let you burst higher when needed. For this short project, CPU credits are never a concern.
- Under Instance type, select t3.micro (marked Free tier eligible).
- Under Key pair (login), select ec2-first-principles from the dropdown.
Next, you will configure the network. A Security Group acts as a firewall for your instance, controlling which traffic is allowed in and out. For now, you will only allow SSH access on port 22. You will add HTTP access in a later step.
- Under Network settings, confirm the default VPC and default subnet are selected.
- Confirm Auto-assign public IP is set to Enable.
- Under Firewall (security groups), select Create security group.
- In the Security group name field, replace the default name with ssh-only.
- Confirm the default inbound rule allows SSH on port 22 from source 0.0.0.0/0 (Anywhere).
How does EBS storage attach to your instance?
EBS (Elastic Block Store) volumes are network-attached storage, not local disks. The Nitro Card on your host connects to the EBS service over the network using the NVMe protocol. Your instance sees the volume as a local NVMe drive, but the actual data lives on separate, redundant storage infrastructure.
gp3 is a general-purpose SSD volume type. Your 8 GiB root volume stores the operating system and everything you install on the instance.
- Under Configure storage, confirm the root volume is set to 8 GiB and gp3 (these are the defaults).
- Click Launch instance.
You should see a success notification with your instance ID.
Observe the instance reaching Running state
After you click Launch instance, a chain of events fires on AWS hardware before your instance is ready.
- Click the instance ID link in the success notification to open the Instances page.
- Select the checkbox next to your web-server-first-principles instance.
- Watch the Instance state column. It starts as Pending and transitions to Running.
What happens during Pending?
During the Pending state, the Nitro Controller is allocating CPU cores and memory on a physical host, attaching your EBS root volume via NVMe, loading the Nitro Hypervisor, and preparing your ENI (Elastic Network Interface) with its security group rules.
Once the hypervisor is ready, the Linux kernel boots, cloud-init runs (configuring SSH keys, hostname, and package repos), and finally sshd starts listening on port 22. Only then does the state flip to Running.
Before you check the details, predict: what public IP address format do you expect to see assigned to your instance?
- In the instance details panel at the bottom of the page, find the Public IPv4 address field.
- Note this IP address down. You will use it in the next step to connect via SSH.
Your instance now has a public IP in a format like 3.92.xxx.xxx. This confirms the ENI was created and a public address was mapped to it.
Review the instance details
Every configuration choice you made in the wizard is now visible in the instance's detail tabs. Confirm each one took effect.
- In the Details tab, confirm the Instance type shows t3.micro.
- Confirm the AMI ID references Amazon Linux 2023.
- Confirm the VPC ID and Subnet ID fields are populated (your default VPC and subnet).
- Click the Security tab and confirm your ssh-only security group is attached with one inbound rule: SSH on port 22.
- Click the Networking tab and note the primary ENI that was automatically created and attached to your instance.
Why does the ENI matter?
The ENI is your instance's network identity. It holds the private IP, the public IP mapping, and the security group association. Traffic does not reach your Linux kernel directly. It arrives at the ENI first, where the Nitro Card evaluates it against the security group rules before forwarding allowed packets to the VM.
Instance stuck in Pending or went to Terminated?
If your instance stays in Pending for more than 2 minutes, refresh the page. If it moved to Terminated, check that you selected an AMI marked Free tier eligible and that your account has no service limit restrictions.
Still stuck? Help me troubleshoot my EC2 instance launch failure.
Your instance is live and has a public IP address. Next up, you will connect to it via SSH and prove the entire boot chain succeeded by landing inside the Linux shell.
Connect via SSH
Your instance is running in the cloud with a public IP address assigned. Now it's time to reach it and prove the entire boot sequence completed successfully.
When you pressed Launch Instance, a chain of events fired behind the scenes. The Nitro Controller allocated CPU cores and memory, the Nitro Hypervisor partitioned those resources for your VM, the EBS root volume attached via NVMe, firmware initialized, GRUB loaded the Linux kernel, systemd started services, cloud-init configured your SSH keys, and finally sshd started listening on port 22. Your SSH connection is the proof that this entire chain succeeded.
In this step, get ready to:
- Connect to your EC2 instance from Windows Terminal using SSH.
- Verify the boot sequence completed by checking system uptime, OS version, and running services.
Connect from Windows Terminal
What happened during boot?
Here is the full chain that fired between you clicking Launch and sshd accepting connections:
- Nitro Controller allocated physical CPU cores and memory on the host server.
- Nitro Hypervisor (a minimal, KVM-based VMM with no shell or file system) partitioned those resources into your isolated VM.
- EBS root volume attached to your VM as an NVMe device via the Nitro Card's SR-IOV virtual function.
- Legacy BIOS firmware initialized (Intel/AMD instance types default to Legacy BIOS boot mode).
- GRUB loaded the Linux kernel from the root volume.
- systemd started services in dependency order.
- cloud-init set the hostname, placed your public key in ec2-user's .ssh/authorized_keys, and prepared package repos.
- sshd started listening on port 22, ready to accept your connection.
- In the EC2 console, click on your web-server-first-principles instance to open its details.
- Find the Public IPv4 address field and copy the address.
Before you run the SSH command, what do you think you'll see if the connection succeeds?
- Connect to your instance by running this command in Windows Terminal:
ssh -i [[PEMPATH="C:\Users\YourUsername\.ssh\ec2-first-principles.pem"]] ec2-user@[[EC2_PUBLIC_IP="your EC2 public IPv4 address"]]
What does this command do?
- ssh invokes the OpenSSH client built into Windows.
- -i specifies the path to your private key file. The server holds your public key (placed by cloud-init). The mathematical relationship between the two proves your identity without a password.
- ec2-user is the default SSH username for Amazon Linux instances.
- The public IP is the address your packets travel to across the internet, through the Internet Gateway, and into your instance's ENI.
What is the fingerprint prompt?
On first connection, SSH displays a message saying the authenticity of the host can't be established, followed by a key fingerprint. This is SSH verifying the server's identity to you (just as your private key verifies your identity to the server).
Type yes and press Enter to accept and continue.
You'll see the prompt change to [ec2-user@ip-... ~]$. You are now inside your EC2 instance.
Connection timed out or permission denied?
- If you see Connection timed out: confirm your instance state is Running in the EC2 console and that the security group allows SSH (port 22) from 0.0.0.0/0.
- If you see Permission denied (publickey): double-check the path to your .pem file is correct and that you're using ec2-user as the username.
- If you see a permissions warning about the key file being too open: right-click the .pem file, go to Properties > Security > Advanced, disable inheritance, and remove all users except your own account.
Still stuck? Help me troubleshoot my SSH connection to EC2.
Verify the system booted correctly
Now that you're inside, you can confirm each layer of the boot sequence did its job.
- Check how long the instance has been running:
uptime
You'll see output showing the system has been up for a few minutes, confirming the kernel booted shortly after you launched.
- Confirm the operating system is Amazon Linux 2023:
cat /etc/os-release
Look for Amazon Linux 2023 in the output. This proves the AMI you selected wrote its OS to the root volume and booted correctly.
- Confirm the SSH daemon is running (this is the service that accepted your connection):
systemctl status sshd
You'll see active (running) in green. This is the systemd service that cloud-init started, listening on port 22 for your key-authenticated session.
- Query the instance metadata service to confirm your instance type from inside the VM:
curl http://169.254.169.254/latest/meta-data/instance-type
You'll see t3.micro printed.
What is 169.254.169.254?
This is a link-local address that every EC2 instance can reach. It serves the instance metadata service, which tells the VM about itself: instance type, public IP, IAM role credentials, and more.
No internet access or DNS is needed to reach it. The Nitro Card intercepts traffic to this address before it leaves the ENI.
Curl returning a 401 or HTML error?
Some newer instances require IMDSv2 (token-based metadata access). If the curl command returns an error instead of t3.micro, try this token-based version instead:
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-type
Need more help? Help me access EC2 instance metadata.
You're connected and you've confirmed the full boot sequence worked: kernel booted, systemd started services, cloud-init configured SSH access, and the metadata service recognizes your t3.micro instance. Next up, you'll deploy a web server and learn what happens when a browser request tries to reach it.
Deploy Nginx and Hit the Designed Failure
You have a live SSH session into your instance, proving the entire boot chain from Nitro Controller to sshd works. Now it's time to make this server do something visible: serve a web page that anyone can reach from their browser.
When a browser sends a request to your instance, the packet travels through multiple layers before the Linux kernel ever sees it. Each layer can accept or silently drop the traffic. Understanding this journey is key to diagnosing why things work locally but fail from outside.
What is the packet journey from browser to Nginx?
When you type your instance's public IP into a browser, here is what happens:
- Your browser resolves the IP and sends a TCP packet destined for port 80.
- The packet crosses the Internet and arrives at the AWS region's Internet Gateway.
- The route table in your VPC directs it to the correct subnet.
- The packet arrives at your instance's Elastic Network Interface (ENI).
- The Security Group attached to the ENI evaluates the packet against its inbound rules. If no rule allows it, the packet is dropped right here.
- Only if the Security Group allows it does the Linux kernel receive the packet and pass it to the listening process (Nginx).
Your current Security Group allows only port 22. Keep that in mind as you deploy your web server.
In this step, get ready to:
- Install and start Nginx as your web server.
- Create a custom HTML page and verify it serves locally.
- Attempt browser access and observe what happens at the Security Group layer.
Install and start Nginx
Nginx is an HTTP server that listens for incoming requests and responds with files. You need to install it, start it, and tell the system to restart it automatically if the instance reboots.
- In your SSH session, install Nginx by running this command:
sudo dnf install -y nginx
You will see DNF download and install the Nginx package along with its dependencies. The output ends with Complete! when finished.
Seeing a 'not found' error?
Make sure you typed dnf (not apt or yum). Amazon Linux 2023 uses DNF as its package manager.
help me troubleshoot a dnf install error on Amazon Linux 2023
- Start Nginx and enable it to launch on boot by running these commands:
sudo systemctl start nginx
sudo systemctl enable nginx
- Verify Nginx is running by checking its status:
systemctl status nginx
You should see active (running) in green text. This confirms Nginx is listening for connections.
What do these commands do?
- sudo dnf install -y nginx downloads and installs Nginx from the AL2023 package repository. The -y flag auto-confirms the install prompt.
- sudo systemctl start nginx tells systemd to launch the Nginx process now.
- sudo systemctl enable nginx creates a symlink so Nginx starts automatically on every future boot.
Create a custom web page
Nginx serves files from its document root at /usr/share/nginx/html/. You will replace the default page with your own HTML so you can confirm your content is being served.
- Create your custom page by running this command:
sudo bash -c 'cat > /usr/share/nginx/html/index.html << EOF
<!DOCTYPE html>
<html>
<head><title>EC2 First Principles</title></head>
<body>
<h1>Hello from EC2</h1>
<p>This page is served by Nginx on Amazon Linux 2023, running on a t3.micro instance powered by the AWS Nitro System.</p>
</body>
</html>
EOF'
What does this command do?
This uses a heredoc (<< EOF) to write multiple lines into a file in one shot. The sudo bash -c wrapper gives the write operation root permissions, which is required because /usr/share/nginx/html/ is owned by root.
- Verify Nginx serves your custom page locally by running:
curl localhost
You should see your custom HTML returned, starting with <!DOCTYPE html> and containing Hello from EC2. This proves Nginx is running and serving your page inside the instance.
Seeing the default Nginx page instead?
If curl localhost returns generic Nginx HTML instead of your custom content, the heredoc command may not have written correctly. Re-run the sudo bash -c command and make sure you copy it exactly, including the single quotes around the entire argument.
help me troubleshoot why my custom index.html is not being served by Nginx
Attempt to access from your browser
Your web page works locally inside the instance. Now test whether the outside world can reach it.
Before you try this, think about what you learned about the packet journey. Your Security Group ssh-only allows inbound TCP on port 22 only. What do you think will happen when your browser sends a request to port 80?
- Open your browser and navigate to your instance's public IPv4 address:
http://[[PUBLIC_IP="your instance's public IPv4 address"]]
- Wait 10-15 seconds and observe what happens.
The page does not load. Your browser eventually shows a timeout or "connection timed out" message. The request never reaches Nginx.
Why does it time out instead of showing an error instantly?
Your Security Group has no rule allowing inbound TCP on port 80. The packet arrives at your ENI, the Nitro Card evaluates it against the Security Group rules, finds no match, and silently drops it. There is no rejection response sent back.
Your browser keeps waiting for a response that will never come. Eventually it gives up and shows a timeout. This is different from a "connection refused" error, which would mean the packet reached the OS but nothing was listening. Here, the packet never enters the VM at all.
This is the designed failure of this step. Nginx is running and working perfectly (you proved that with curl localhost). The gap is in your Security Group, which blocks port 80 at the ENI layer before traffic ever touches the Linux kernel.
The timeout proves your Security Group is doing exactly what you told it to do. Next, you will add a rule to let HTTP traffic through and complete the packet journey from browser to Nginx.
Fix the Security Group
In the previous step, you deployed Nginx, confirmed it was serving your page locally, and then watched your browser time out when you tried to access it from the outside.
That timeout proves something important: Security Groups are not firewall rules running inside your instance. They are enforced at the ENI level by the Nitro Card, before traffic ever enters the VM. This is also why they are stateful without consuming instance CPU. The Nitro hardware handles connection tracking, not your Linux kernel.
In this step, get ready to:
- Add an HTTP inbound rule to your security group to allow port 80 traffic.
- Verify the complete packet journey from your browser to Nginx and back.
Add HTTP access to the security group
Your ssh-only security group currently has a single inbound rule: TCP port 22 for SSH. You need to add a second rule that permits HTTP traffic on port 80.
- In the EC2 Console, click Security Groups in the left sidebar under Network & Security.
- Select the checkbox next to your ssh-only security group.
- Click the Inbound rules tab in the details pane below.
- Click Edit inbound rules.
- Click Add rule.
- Set the Type dropdown to HTTP. This automatically fills in Port 80 and Protocol TCP.
- Set the Source dropdown to Anywhere-IPv4 (0.0.0.0/0).
- Click Save rules.
Why does this take effect immediately?
Security group rule changes apply instantly because the rules live on the Nitro Card attached to your ENI, not inside your instance's operating system. When you save the new rule, AWS pushes it to the Nitro hardware. There is no service to restart or config file to reload.
You should now see two inbound rules listed: SSH on port 22 and HTTP on port 80, both from 0.0.0.0/0.
Only see one rule?
Make sure you clicked Add rule to create a new row, then Save rules at the bottom. If you edited the existing SSH rule instead of adding a new one, delete it and re-add both SSH and HTTP as separate rules.
Need help?
Verify from your browser
The same request that timed out moments ago should now succeed. The packet takes the same path it did before, but this time the security group sees a matching ALLOW rule for TCP port 80 and lets it through to the Linux kernel.
Before you refresh, think about this: what do you expect to see, and why should it work now when it failed 30 seconds ago?
- Switch back to your browser tab that showed the timeout.
- Refresh the page at http://<public-ip> (use the same public IPv4 address from your instance details).
Your custom page loads. You should see the "Hello from EC2" heading and the paragraph about Nginx on Amazon Linux 2023.
What is the complete packet journey?
Your browser request now traverses the full path successfully:
- Browser resolves your public IP via DNS and sends an HTTP request.
- The packet crosses the Internet to the AWS region and enters through the Internet Gateway.
- The route table directs it to your subnet, where it arrives at your ENI.
- The Security Group evaluates the packet against its rules and finds the port 80 ALLOW. It passes through.
- The Linux kernel receives it and hands it to Nginx, which sends back your HTML page.
- The response flows back automatically because Security Groups are stateful. The return traffic is tracked and permitted without an explicit outbound rule for port 80.
Still seeing a timeout?
Confirm that you saved the new rule (check the Inbound rules tab shows HTTP on port 80). Also make sure you are using http:// and not https:// in your browser URL. HTTPS uses port 443, which is not open.
If you copied the IP address, double check it matches the Public IPv4 address in your instance details (not the private IP).
Need help?
Your web server is live and publicly accessible. You have seen both sides of the security group coin: the silent drop when traffic is not permitted, and the instant fix when you add the rule. Next up, you will create a golden image from this configured instance so you can launch identical copies without any manual setup.
Secret mission
Create a Golden Image
Platform engineers never configure servers by hand in production. They build golden images: pre-configured AMIs that capture the exact state of a working server, so identical copies launch in seconds. Can you create a custom AMI from your instance and launch a clone that serves your page with zero manual setup?
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. Both EC2 instances are Free Tier eligible (t3.micro), but running two instances consumes your 750 free hours per month twice as fast.
Cost warning
Two running t3.micro instances use 2 hours of Free Tier credit per clock hour. If you leave both running for the entire month, you will exceed the 750-hour monthly limit and begin incurring charges. Stop or terminate the instances when you are not actively using them.
Resources you used:
- 2 EC2 instances (t3.micro) - Free Tier eligible, billed if running beyond 750 hrs/month total.
- 1 custom AMI (nginx-golden-image) with an associated EBS snapshot - minimal storage cost.
- 1 key pair (ec2-first-principles) - no cost.
- 2 security groups (ssh-only and the second instance's group) - no cost.
- 1 local private key file (ec2-first-principles.pem) on your Windows machine.
Keep everything running
No action needed. Choose this if you are still actively experimenting with your instances or want to practise SSH and Nginx configuration further.
- Monitor your Free Tier usage in the AWS Billing dashboard to avoid surprise charges.
- Both instances and the AMI will remain available in your account.
- The local ec2-first-principles.pem file stays on your machine for future SSH connections.
Pause - I'll come back to this later
Stop both instances to eliminate compute charges while preserving your setup. You will incur a small EBS storage charge for the root volumes while stopped.
- In the EC2 console, choose Instances in the navigation pane.
- Select both instances (web-server-first-principles and the second instance).
- Choose Instance state, then Stop instance.
- Choose Stop when prompted for confirmation.
- When you are ready to resume, select the instances and choose Instance state, then Start instance. Note that the public IPv4 addresses will change on restart.
Delete - I don't want to use this again
Remove all project resources and start fresh. Follow these steps in order.
Terminate both EC2 instances:
- In the EC2 console, choose Instances in the navigation pane.
- Select both instances (web-server-first-principles and the second instance).
- Choose Instance state, then Terminate (delete) instance.
- Choose Terminate (delete) when prompted for confirmation.
- The instances will show as terminated briefly and then disappear from the console.
Deregister the custom AMI and delete the snapshot:
- In the navigation pane, choose AMIs.
- Select nginx-golden-image.
- Choose Actions, then Deregister AMI.
- Select the Delete associated snapshots checkbox to remove the EBS snapshot at the same time.
- Choose Deregister AMI to confirm.
Delete the key pair:
- In the navigation pane, choose Key Pairs.
- Select ec2-first-principles and choose Actions, then Delete.
- Type Delete in the confirmation field and choose Delete.
Delete the security groups:
- In the navigation pane, choose Security Groups.
- Select the ssh-only security group and the second instance's security group.
- Choose Actions, then Delete security groups.
- Enter Delete when prompted and choose Delete.
Delete the local private key file:
- Open Windows Terminal and run:
del C:\Users\$env:USERNAME\.ssh\ec2-first-principles.pem
- If you stored the file in a different location, navigate there and delete ec2-first-principles.pem manually.
That's a Wrap!
That's a Wrap!
Nice work! You just launched, connected to, and deployed a web server on EC2 with full understanding of what is happening at every layer, from the Nitro Hypervisor to the HTTP response.
You've learned how to:
- Launch an EC2 instance with full understanding of what virtualization, the Nitro System, AMIs, instance types, and EBS volumes represent at the engineering level.
- Deploy Nginx and experience the designed failure where Security Groups block traffic at the ENI level before it ever reaches the Linux kernel.
- Fix the Security Group and verify the complete packet journey from browser to Nginx response, proving that Security Groups are stateful and enforced by the Nitro Card hardware.
- Secret Mission: Created a golden image (custom AMI) and launched a second identical server from it with zero manual configuration, demonstrating the immutable infrastructure pattern used by platform engineers in production.
Ready to quiz yourself?