Amazon EC2 is the compute building block of AWS: virtual servers you can provision in minutes, resize on demand, and tear down when done. This lesson covers regions, AMIs, instance types, key pairs, security groups, EBS storage, pricing models, and a step-by-step launch of your first Linux web server — the natural next stop after IAM on the AWS roadmap.

1. Learning Objectives

By the end of this lesson, you will be able to:

  • Explain what Amazon EC2 is and where it fits in the AWS compute stack
  • Choose a region, AMI, and instance type that match a workload
  • Launch an EC2 instance from both the AWS CLI and the console
  • Connect to a Linux instance over SSH using a key pair
  • Secure instances with security groups and IAM instance profiles
  • Manage EBS volumes, snapshots, and the instance lifecycle
  • Compare On-Demand, Reserved, and Spot pricing and estimate monthly cost

2. Why This Matters

Imagine your startup just got its first paying customers and the demo server running on a laptop is no longer an option. You need a real server, in the cloud, that you can provision in minutes, resize when traffic spikes, and tear down when you are done. Amazon EC2 (Elastic Compute Cloud) is that building block: a virtual server you rent by the second, with your choice of CPU, memory, storage, and operating system.

Almost every architecture you will meet in AWS — a load balancer in front of web servers, a bastion host for SSH access, a worker fleet processing queues, even the control planes of EKS and ECS — is built on EC2 instances under the hood. If you understand EC2, you understand the compute layer that everything else sits on. That is why it is the natural second stop on the AWS roadmap, right after IAM.

3. Core Concepts

EC2 is simple on the surface — rent a server — but the vocabulary around it can be overwhelming. Here are the building blocks you will use every day:

  • Region and Availability Zone: a Region is a geographic area (e.g. us-east-1, eu-west-1); each Region has 3+ isolated Availability Zones (AZs) for high availability. Instances live in one AZ.
  • AMI (Amazon Machine Image): the golden image of the OS plus any preinstalled software. Amazon Linux 2023, Ubuntu, and Rocky Linux are common choices.
  • Instance type: the hardware profile. The naming convention is family, generation, and size: t3.micro = general-purpose family t, generation 3, micro size (2 vCPU / 1 GiB).
  • Key pair: the SSH credential. AWS keeps the public key; you keep the private .pem file and use it to log in.
  • Security group: a virtual firewall attached to the instance. Default-deny inbound, allow-list rules only (e.g. SSH from your IP, HTTP from anywhere).
  • EBS volume: the network-attached block storage. The root volume boots the OS; you can attach extra volumes and take point-in-time snapshots.
  • Lifecycle: instances move through pending, running, stopping/stopped (keep storage, stop billing for compute), and terminated (deleted).

Instance families map to workloads — this is the table I keep next to my desk:

FamilyUse caseExample
t (burstable)Web servers, dev/testt3.micro, t3.medium
m (general)Balanced apps, app serversm5.large, m6i.xlarge
c (compute)CI runners, batch, mediac6i.large
r (memory)Caches, databases, in-memoryr6g.large
g (GPU)ML training, renderingg4dn.xlarge

Finally, two concepts that keep your bill (and your security) in check:

  • Pricing models: On-Demand (flexible, per-second), Reserved Instances / Savings Plans (1-3 year commitment, up to 72% cheaper), Spot (up to 90% cheaper, can be reclaimed with 2-minute notice — perfect for stateless workers).
  • IAM instance profile: instead of pasting access keys onto a server, you attach an IAM role to the instance. The AWS SDK on the box automatically rotates temporary credentials for you — this is the least-privilege pattern IAM lesson 9.1 prepared you for.

4. Hands-On Practice

We will launch a small web server step by step. Prerequisites: the AWS CLI installed and configured with an IAM user that has EC2 and IAM read permissions (follow the IAM lesson if you have not created one yet).

aws configure
AWS Access Key ID [None]: AKIA...EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: eu-west-1
Default output format [None]: json
Step 1: Point the CLI at your account (use your own keys, never share them)
aws ec2 create-key-pair \
  --key-name my-dev-key \
  --key-type ed25519 \
  --query 'KeyMaterial' \
  --output text > my-dev-key.pem
chmod 400 my-dev-key.pem
Step 2: Create a key pair and lock down the private key permissions
aws ec2 run-instances \
  --image-id ami-0abcdef1234567890 \
  --instance-type t3.micro \
  --key-name my-dev-key \
  --security-groups default \
  --associate-public-ip-address \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-server-1}]'
Step 3: Launch a t3.micro instance (replace the AMI id with one for your region)
INSTANCE_ID=$(aws ec2 run-instances --image-id ami-0abcdef1234567890 \
  --instance-type t3.micro --key-name my-dev-key --query 'Instances[0].InstanceId' \
  --output text)
echo "Instance: $INSTANCE_ID"
aws ec2 wait instance-running --instance-ids "$INSTANCE_ID"
aws ec2 describe-instances --instance-ids "$INSTANCE_ID" \
  --query 'Reservations[0].Instances[0].PublicIpAddress' \
  --output text
Step 4: Capture the instance id, wait for running, and read its public IP
kubectl get pods -w
$ ssh -i my-dev-key.pem ec2-user@54.170.123.45
The authenticity of host '54.170.123.45' can't be established.
ED25519 key fingerprint is SHA256:9lB4m6VwXyZ...
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '54.170.123.45' (ED25519) to the list of known hosts.
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ \~___/
[ec2-user@ip-172-31-24-8 ~]$
Step 5: You are in — this is the SSH banner of a freshly launched Amazon Linux 2023 box
sudo dnf update -y
sudo dnf install -y nginx
sudo systemctl enable --now nginx
curl -s -o /dev/null -w '%{http_code}\n' http://localhost
# 200
Step 6: Install and start nginx, then verify it answers on localhost
# Stop billing for compute (root volume is kept, instance can be started again)
aws ec2 stop-instances --instance-ids i-0abc123def4567890

# Permanently delete the instance
aws ec2 terminate-instances --instance-ids i-0abc123def4567890
Step 7: Clean up — stop saves money, terminate removes the instance for good

5. Common Errors & Solutions

1. SSH hangs, then "Connection timed out"
Cause: no inbound SSH rule on the security group, or you are connecting from a different IP than the rule allows. Fix: add an inbound rule for TCP 22 from your current public IP (curl ifconfig.me to find it).

2. "Permission denied (publickey)"
Cause: wrong key pair, or you are logging in as the wrong user. Amazon Linux uses ec2-user, Ubuntu uses ubuntu. Fix: connect as ssh -i my-dev-key.pem ec2-user@IP and make sure the key pair matches the one chosen at launch.

3. "Unprotected private key file"
Cause: the .pem file has loose permissions and OpenSSH refuses to use it. Fix: chmod 400 my-dev-key.pem.

4. "InsufficientInstanceCapacity" on launch
Cause: the chosen AZ is out of capacity for that instance type. Fix: retry in a different AZ, use a slightly different size, or switch the purchase option to On-Demand if you were using a capacity-constrained plan.

5. Site loads on the instance but not from the browser
Cause: nginx is running but the security group has no inbound rule for TCP 80/443. Fix: add 0.0.0.0/0 on port 80 (and 443) to the security group — and remember this is also the classic mistake behind "I installed nginx but my site is down" tickets.

6. Summary Checklist

  • I can pick a Region and AZ and explain why the choice matters for latency and HA
  • I can decode an instance type name (t3.micro) and pick a family for a workload
  • I created a key pair and protected the private key with chmod 400
  • I launched an instance via the CLI, waited for it, and read its public IP
  • I connected over SSH and installed nginx on Amazon Linux
  • I know the difference between stop (keep storage) and terminate (delete)
  • I attached an IAM instance profile instead of hardcoding access keys

7. Practice Exercise

Exercise: deploy and harden a web server.

  1. Launch a t3.micro Amazon Linux instance in the same Region as your IAM user, with a tag Name=exercise-web.
  2. SSH in and install nginx; verify it returns HTTP 200 on localhost.
  3. Create a security group that allows SSH only from your IP and HTTP from 0.0.0.0/0, then attach it to the instance.
  4. Load the public IP in your browser and confirm the nginx welcome page renders.
  5. Take an EBS snapshot of the root volume.
  6. Stop the instance, confirm the IP disappears, start it again, and confirm the web server still works — then terminate it and delete the snapshot.

Bonus: repeat the launch using a Spot instance and compare the price in the EC2 console pricing history.

8. Next Steps

You now have compute — next comes storage. The AWS roadmap continues with Lesson 9.3: S3 (Storage), where you will learn object storage, bucket policies, versioning, and lifecycle rules. After that, Lesson 9.4: VPC (Networking) will show you how to give these EC2 instances a real, isolated network instead of the default VPC. See you there!

Gataya Med

DevOps Engineer & Backend Developer. Sharing insights on cloud, automation, and scalable systems.

Comments (0)

Sarah Chen August 1, 2026

This is exactly what I needed! The initContainer approach solved our migration issues completely. Thanks for the detailed guide!

Reply

Leave a Comment