DEV Community

Tejas Shinkar
Tejas Shinkar

Posted on • Edited on

AWS EC2 Essentials — Compute, Storage, Networking, Lifecycle & CLI

EC2 Essentials

Compute · ENI · EBS · AMI · Key Pairs · Security Groups · Elastic IP · Lifecycle · Placement Groups · CLI


Part of my AWS learning journey — transitioning from Systems Engineer to Cloud/DevOps. EC2 is the foundation of AWS compute — understanding it deeply makes everything else make sense.


📋 Topics Covered

# Topic Type
1 What is EC2 & Why Named EC2 Concept
2 EC2 Instance Types & Families Concept + Cert
3 AWS Compute Optimizer Concept + DevOps
4 Elastic Network Interface (ENI) Concept + Interview
5 Amazon EBS — Persistent Storage Concept + Lab
6 EBS Volume Types & IOPS Concept + Cert
7 EBS Snapshots & Cross-Region Copy Concept + Lab
8 EBS Multi-Attach & Encryption Concept + Cert
9 EBS vs S3 Concept + Interview
10 Instance Store — Temporary Storage Concept + Cert
11 AMI — Types, Selection & Sharing Concept + Lab
12 EC2 Key Pairs Concept + Lab
13 Security Groups Concept + Interview
14 Elastic IP & Billing Estimation Concept + Lab
15 EC2 Lifecycle — Start, Stop, Hibernate, Terminate Concept + Cert
16 EC2 Status Checks Concept + Cert
17 EC2 Placement Groups Concept + Cert
18 AWS CLI — Installation, Config & EC2 Commands Practical
19 boto3 — Python SDK for EC2 Practical
20 Lab 1 — Launch EC2 as Web Server with User Data Lab
21 Lab 2 — EC2 + S3 Access via Instance Profile Lab
22 Lab 3 — EC2 Resize & EBS Volume Resize Lab
23 Lab 4 — Custom AMI Creation & Validation Lab
24 Lab 5 — EBS Snapshot Cross-Region Copy Lab

What is EC2 & Why Named EC2

Before cloud, running an application meant buying a physical server — weeks of procurement, rack installation, OS setup, then maintenance forever. EC2 changed that entirely.

EC2 = Elastic Compute Cloud — a virtual server running on AWS hardware that you can provision in minutes, pay for by the second, and terminate when done.

Why "Elastic Compute Cloud"? The "2" in EC2 is simply because "Elastic Compute Cloud" has two C's — it's a playful naming convention. More meaningfully: Elastic because it scales on demand (up or down, instantly), Compute because it provides raw processing power, and Cloud because it's delivered over the internet from AWS data centers.

The name breaks down:

  • E — Elastic → scale up or down on demand, any time
  • C — Compute → processing power (CPU, RAM, GPU) for your workloads
  • C — Cloud → delivered over the internet from AWS data centers, not from your office

EC2 Instance Types — Choosing the Right Size

Every EC2 instance has a type — a predefined combination of CPU, RAM, storage, and network capacity. AWS groups them into families, each optimized for a different workload.

Analogy: Instance types are like vehicles. You don't drive a truck to pick up groceries, and you don't use a hatchback to transport 10 tonnes of cargo. Right tool for the right job.

Family Examples Optimized For Real Use Case
General Purpose t3, m6i Balanced CPU + RAM Web servers, small databases, dev environments
Compute Optimized c5, c6g High CPU Batch processing, ML inference, gaming servers
Memory Optimized r5, x2 Large RAM In-memory databases, Redis, SAP HANA
Storage Optimized i3, i4i Fast local NVMe disk NoSQL databases, data warehousing, Elasticsearch
Accelerated Computing p3, g4dn GPU ML training, video rendering, scientific computing

Instance naming — how to read it:

t3.mediumt = family (general purpose, burstable) · 3 = generation (higher = newer, better price/performance) · medium = size (nano → micro → small → medium → large → xlarge → 2xlarge...)

Free Tier: t2.micro or t3.micro — 750 hours/month for 12 months. Use this for all labs.

🎯 Cert tip: SAA-C03 frequently gives a scenario and asks which instance family fits. Know the families — especially General Purpose (t/m), Compute (c), Memory (r), Storage (i/d), GPU (p/g).

AWS Compute Optimizer

If you already have EC2 running in production and want to know if you're over or under-provisioned, AWS Compute Optimizer analyses your actual CloudWatch utilization data and recommends the optimal instance type.

For example: you launched a c5.2xlarge for a web server, but Compute Optimizer sees CPU is consistently at 8% — it recommends a t3.medium at 60% lower cost.

Useful in production cost reviews. Not needed during initial setup or learning.


ENI — Elastic Network Interface

ENI = Elastic Network Interface — the virtual network card that gives your EC2 instance its network identity. Every EC2 instance gets a primary ENI automatically at launch.

Analogy: ENI is like a SIM card in a phone. The phone (EC2) needs the SIM (ENI) to have a phone number (IP address), connect to a network, and send/receive data. The SIM can be moved to a different phone — and the phone number comes with it.

What an ENI carries:

Attribute What it is
Private IPv4 Internal IP within your VPC — always present, never changes
Public IPv4 Internet-facing IP — assigned if enabled, changes on stop/start
Elastic IP Static public IP you allocate separately — doesn't change
IPv6 Optional, if the VPC has IPv6 enabled
MAC Address Unique hardware identifier — used for software licensing
Security Groups Firewall rules — applied at the ENI level, not the instance level

Why ENI lives at the interface level (not instance level):

Security Groups and IPs are properties of the ENI, not the EC2 instance directly. When you "change the security group on an EC2," you're actually changing it on the primary ENI. This distinction matters when you have multiple ENIs on one instance — each can have different security groups.

Why multiple ENIs on one instance:

  • Separate management traffic from application traffic (e.g., one ENI on a private subnet, one on a management subnet)
  • Move a network identity from a failed instance to a healthy one — the Elastic IP and Security Groups travel with the ENI

🎯 Interview tip: "How do you move an Elastic IP from a failed EC2 to a replacement instance with zero client-side change?" — Detach the ENI from the failed instance and attach it to the replacement. Or disassociate and reassociate the Elastic IP. The client's connection target never changes.


EBS — Persistent Storage for EC2

EBS = Elastic Block Store — the hard disk for your EC2 instance. It's where your OS, application files, and data live.

Analogy: EC2 is your laptop. EBS is the hard drive inside it. If you sell the laptop (terminate EC2), you can remove the hard drive first (detach EBS) and plug it into a new laptop (attach to new EC2). The data stays intact.

Key characteristics:

  • Persistent — data survives EC2 stop/restart (unlike Instance Store)
  • Network-attached — connected via high-speed AWS network, not physically inside the EC2 host
  • AZ-locked — lives in one specific AZ, can only attach to EC2 in the same AZ
  • Replicated within AZ — AWS replicates within the AZ for durability (not cross-AZ)
  • Independently scalable — you can resize EBS without replacing the EC2 instance

EBS Volume Types

Type IOPS Throughput Best For
gp3 (General Purpose SSD) 3,000–16,000 Up to 1,000 MB/s Default choice for most workloads
gp2 (Legacy General Purpose SSD) Up to 16,000 250 MB/s Older default — prefer gp3 for new volumes
io2 (Provisioned IOPS SSD) Up to 64,000 1,000 MB/s High-performance databases, SAP, Oracle
st1 (Throughput Optimized HDD) N/A Up to 500 MB/s Big data, log processing, Kafka
sc1 (Cold HDD) N/A Up to 250 MB/s Infrequent access, archival, cheapest

IOPS = Input/Output Operations Per Second — how many read/write operations your storage handles per second.

Analogy: IOPS is like a highway's capacity. gp3 is a 4-lane road — handles normal traffic well. io2 is a 10-lane expressway — built for when hundreds of database queries are rushing through every second.

🎯 Cert tip: gp3 = default choice. io2 = high-IOPS databases. The difference between gp3 and gp2: gp3 allows you to independently set IOPS and throughput (not tied to volume size like gp2). Always choose gp3 for new volumes.

EBS Snapshots

A Snapshot is a point-in-time backup of your EBS volume, stored in S3 (you don't see the S3 bucket — AWS manages it internally).

  • Incremental — first snapshot is a full copy. Each subsequent snapshot only stores what changed since the last one. Saves significant cost and time.
  • Cross-AZ/Region capable — a snapshot in Mumbai can be used to create a volume in Singapore
  • AMI source — custom AMIs are built from snapshots
  • No instance downtime required — snapshots can be taken while the instance is running

When to take snapshots:

  • Before making any significant change to your server (patching, config changes)
  • Before terminating an instance that has data you might need
  • Scheduled backups for production systems (use AWS Backup for automation)
  • When copying data to another AZ or Region

🎯 Cert scenario: "How do you move EBS data to a different AZ?" — EBS is AZ-locked so you can't move it directly. Take a snapshot → create a new volume from the snapshot in the target AZ → attach to the EC2 in that AZ.

EBS Multi-Attach

Normally: one EBS volume → one EC2 instance. Multi-Attach breaks this rule for specialized workloads.

  • Only available on io1 or io2 volumes
  • Attach one volume to up to 16 EC2 instances simultaneously within the same AZ
  • Requires a cluster-aware file system (Oracle OCFS2, GFS2) — standard Linux file systems like ext4 or xfs cannot handle concurrent writes safely
  • Use case: clustered high-availability databases

🎯 Interview tip: "Can two EC2 instances share the same EBS volume?" → Yes, but only with io1/io2 Multi-Attach, only in the same AZ, and only with a cluster-aware file system.

EBS Encryption

  • Encrypts data at rest (stored on disk) and in transit (moving between EC2 and EBS over the network)
  • Uses AWS KMS keys — either AWS-managed or customer-managed
  • Zero performance impact — encryption/decryption happens transparently in hardware
  • Snapshots of encrypted volumes are automatically encrypted
  • Can be enabled as account-level default — all new volumes encrypted automatically

EBS vs S3 — The Common Confusion

EBS S3
Type Block storage (like a hard disk) Object storage (like file storage)
Access Attached to one EC2 instance Via API/URL from anywhere
Use For OS, databases, application files Images, videos, backups, static sites
Scope AZ-specific Region-wide, globally accessible
Persistence Survives stop/restart Permanent until you delete
Analogy Internal hard drive Google Drive in the cloud

Instance Store — Fast but Temporary

Instance Store is physical storage built directly into the EC2 host machine. It's not a separate network volume — it's the actual spinning disk or NVMe SSD on the physical server your EC2 runs on.

Analogy: Instance Store is RAM in your laptop — extremely fast because it's physically right there, but completely wiped when you turn off the machine.

Instance Store EBS
Speed Very high (physically attached) High (network-attached)
Persistence ❌ Lost on stop/terminate/host failure ✅ Persists
Cost Included with certain instance types Charged separately per GB
Use Case Temporary buffers, caches, scratch space OS, databases, any persistent data

⚠️ Never store anything you need long-term on Instance Store. If the instance stops, terminates, or the underlying hardware fails — data is gone with zero recovery path. This includes planned stops, not just crashes.


AMI — Amazon Machine Image

AMI = Amazon Machine Image — a pre-built template containing everything needed to launch an EC2 instance: the OS, installed software, configuration, and the root volume snapshot.

Analogy: AMI is like a cookie cutter. Once you have the perfect cookie shape (your configured server), you can stamp out identical copies as many times as you want, instantly.

AMI Types — EBS-Backed vs Instance Store-Backed

EBS-Backed AMI Instance Store-Backed AMI
Root volume EBS snapshot S3-stored template
Can stop instance? ✅ Yes ❌ No — can only terminate
Boot time Faster Slower
Persistence Root data survives stop Root data lost on stop
Use for Everything — production, dev, test Legacy workloads

Always use EBS-backed AMIs. Instance Store-backed is legacy and rarely used today.

AMI Sources

Source What it is
AWS Provided Amazon Linux 2/2023, Ubuntu, Windows — official, regularly patched
AWS Marketplace Pre-built commercial or open-source AMIs (WordPress, Nginx, Oracle)
Community AMIs Shared by other AWS users — use with caution, verify before use
Custom AMI You build from a configured EC2 instance — your exact setup, reusable

AMI Selection

When choosing an AMI, consider:

  • OS — Amazon Linux 2023 for AWS-optimized workloads, Ubuntu for developer familiarity
  • Architecture — x86_64 (most common) vs arm64 (Graviton — cheaper, better price/performance)
  • Virtualization — HVM (hardware virtual machine) — the only current option for modern instances
  • Region — AMIs are Region-specific. Same AMI ID doesn't exist in another Region

AMI Sharing

AMIs can be shared in three ways:

Private (default): Only your account can use it.

Shared with specific accounts: You provide AWS account IDs — only those accounts can launch from your AMI. Common in multi-account organizations (share a golden image from a build account to all environment accounts).

Public: Anyone in any AWS account can use it. This is how community AMIs work.

Important: When you share an AMI, you're sharing the snapshot permissions, not the data itself. The recipient can launch instances from your AMI but cannot access your original snapshot directly.

Encryption + Sharing caveat: If your AMI is encrypted with a KMS key (Customer Managed Key), you must also share that KMS key with the target account — otherwise they can't decrypt the snapshot to launch from it. AWS-managed keys cannot be shared across accounts, so encrypted AMIs shared across accounts must use Customer Managed KMS keys.

AMI is Region-specific — to use in another Region:

EC2 Console → AMIs → select AMI → Actions → Copy AMI → choose target Region → Copy. A new AMI ID is created in the target Region.


EC2 Key Pairs

A Key Pair is a public-private cryptographic pair used to authenticate to EC2 without a password.

How it works:

You create a Key Pair in AWS Console.
AWS stores the public key on your EC2 instance (in ~/.ssh/authorized_keys).
You download the private key — a .pem file. Once only. Never again.
To connect: ssh -i my-key.pem ec2-user@<public-ip>
EC2 verifies: "Does this private key match my public key?" → Yes → Access granted.

Access methods by OS:

  • Linux/Mac: SSH with .pem file
  • Windows: Convert .pem to .ppk for PuTTY, or use Windows native SSH (newer versions)
  • Browser (EC2 Instance Connect): No key needed — direct from Console, works for Amazon Linux and Ubuntu

⚠️ If you lose your .pem file, you lose SSH access permanently. AWS has no recovery path. Store it safely. Never check it into Git. Never share it.


Security Groups

A Security Group is a stateful virtual firewall that controls what traffic can reach your EC2 instance — applied at the ENI level.

Analogy: A Security Group is the bouncer at a club entrance. You give the bouncer a list of rules — only people matching the list get in. Everyone else is turned away by default.

Default behaviour:

  • Inbound: deny all — nothing gets in unless explicitly allowed
  • Outbound: allow all — everything can leave

Stateful — what this means:

If you allow inbound traffic on port 80, the response traffic automatically goes out — you don't need a separate outbound rule for it. The Security Group tracks the connection and knows the response belongs to an allowed inbound request.

Common rules:

Purpose Protocol Port Source
SSH access TCP 22 Your IP only (never 0.0.0.0/0 in production)
Web server (HTTP) TCP 80 0.0.0.0/0 (public)
Web server (HTTPS) TCP 443 0.0.0.0/0 (public)
Windows RDP TCP 3389 Your IP only
Database (MySQL) TCP 3306 App server's Security Group

⚠️ Never open port 22 to 0.0.0.0/0 in production. Bots scan the entire internet for open SSH ports constantly. Restrict SSH to your specific IP or use a Bastion Host.

🎯 Interview tip: "Difference between Security Group and NACL?" — Security Group is stateful, operates at the instance/ENI level, Allow rules only. NACL is stateless, operates at the subnet level, Allow and Deny rules. Security Groups are your first layer; NACLs are a second optional layer.


Elastic IP & Billing Estimation

Elastic IP

By default, when you stop and restart an EC2 instance, its public IP changes. This breaks DNS, client configurations, and whitelists.

Elastic IP solves this — a static public IPv4 address that stays assigned to your account until you release it.

Pricing — the trap people fall into:

  • Free when associated with a running EC2 instance
  • Charged (~$0.005/hr ≈ ₹0.40/hr) when allocated but not associated or associated with a stopped instance

⚠️ Always release Elastic IPs after labs. An unattached Elastic IP silently charges you every hour. AWS charges for idle IPs to discourage hoarding of public IPv4 addresses.

Steps:

Allocate: EC2 Console → Elastic IPs → Allocate Elastic IP Address → Allocate

Associate: Select the Elastic IP → Actions → Associate → choose Instance → Associate

Disassociate: Select the Elastic IP → Actions → Disassociate

Release (stop charges): Select the Elastic IP → Actions → Release Elastic IP Address

Billing Estimation

Before deploying anything in AWS, estimate the cost first using AWS Pricing Calculator at calculator.aws.

How to use:

Go to calculator.aws → Create estimate → Add service (EC2) → Select Region (ap-south-1) → Choose instance type, OS, and hours per month → Add EBS storage → Add data transfer if needed → View monthly estimate

Key EC2 billing components:

Component How Charged
Instance compute Per second (minimum 60 seconds), based on instance type + OS
EBS storage Per GB-month (charged even when instance is stopped)
EBS snapshots Per GB-month stored in S3
Elastic IP (idle) Per hour when not attached to a running instance
Data transfer OUT Per GB leaving AWS to the internet

Three pricing models:

Model Commitment Savings Use When
On-Demand None 0% Learning, unpredictable workloads
Reserved Instances 1–3 years 30–70% Steady production workloads running 24/7
Spot Instances None (can be interrupted) Up to 90% Batch jobs, fault-tolerant workloads

EC2 Lifecycle — Start, Stop, Hibernate, Terminate

Every EC2 instance goes through states. Understanding what each state means for billing and data is critical.

State flow:

Launch → Pending (starting up, not billed yet) → Running (operational, billed per second) → Stopping → Stopped (EBS still billed, compute not billed, can restart) → Terminated (deleted forever, not recoverable)

State Compute Billing EBS Billing Data Preserved Recoverable
Running ✅ Yes ✅ Yes Yes
Stopped ❌ No ✅ Yes EBS data yes, RAM no ✅ Yes
Hibernated ❌ No ✅ Yes EBS + RAM (to disk) ✅ Yes
Terminated ❌ No ❌ No (deleted) ❌ No ❌ Never

EC2 Hibernate

Hibernate is like putting your laptop to sleep — the instance pauses, RAM contents are written to the EBS root volume, and when you start it again, the OS resumes exactly where it left off.

Why it exists:

Stop: OS shuts down → restart boots the OS from scratch → applications restart → takes time

Hibernate: RAM saved to EBS → restart restores RAM → OS and applications resume instantly → no boot time

Requirements for Hibernate:

  • Root EBS volume must be encrypted (required — RAM contents are sensitive)
  • Root EBS must have enough free space to hold all RAM contents
  • Instance must be configured to allow hibernation at launch (can't enable after launch)
  • Maximum hibernate duration: 60 days
  • Not available on all instance types — check AWS documentation

Use case: Long-running processes that are expensive to restart (ML training checkpoints, complex application states, developer environments you want to resume quickly).


EC2 Status Checks

AWS automatically runs health checks on every EC2 instance every minute.

System Status Check — checks the AWS infrastructure (power, network, hardware host)

  • If this fails: problem is on AWS's side — the physical host has an issue
  • Fix: Stop and Start the instance. This moves it to a new physical host. Do NOT just reboot — that keeps it on the same failing host.

Instance Status Check — checks the OS and software inside your EC2

  • If this fails: problem is inside your instance — OS crashed, kernel panic, file system corruption
  • Fix: Reboot the instance to restart the OS, or SSH in and fix the issue directly

EBS Volume Status Check — checks attached EBS volumes for IO impairment

  • If this fails: EBS volume is degraded and not serving reads/writes properly
  • Fix: Detach and reattach the volume, or restore from snapshot

🎯 Classic cert question: "Your EC2 system status check fails. What do you do?" → Stop and Start (NOT Reboot). Reboot keeps it on the same host and won't fix a hardware-level failure.

CloudWatch Integration: Set alarms on status checks to trigger automatic recovery actions — this is how production systems self-heal without human intervention.


EC2 Placement Groups

When you launch multiple EC2 instances, AWS decides where to place them on physical hardware. Placement Groups let you control this placement strategy.

Three strategies:

Cluster — all instances packed tightly in one AZ, on hardware physically close together

  • Ultra-low latency between instances, highest network throughput (up to 10 Gbps between instances)
  • Risk: if the rack fails, all instances are affected
  • Use for: HPC (High Performance Computing), ML training requiring fast inter-node communication, Hadoop/Spark jobs

Spread — each instance on a separate physical rack, even separate data centers within an AZ

  • Maximum fault isolation — rack failure only affects one instance
  • Limit: max 7 instances per AZ per Spread placement group
  • Use for: small groups of critical instances that absolutely cannot fail together (master nodes, critical databases)

Partition — instances grouped into partitions (groups of racks), each partition isolated from others

  • Balance of performance and fault isolation
  • Each partition can have many instances; partitions don't share hardware
  • Use for: Hadoop, Kafka, Cassandra, HBase — distributed systems with many nodes per logical group

Analogy:

  • Cluster = teammates at the same table — fast communication, but one fire affects all
  • Spread = teammates in different buildings — isolated, but limited seats per building
  • Partition = teammates on different floors of the same building — grouped but isolated from other floors

🎯 Cert scenarios: "Lowest latency between instances" → Cluster. "7 critical instances must never fail together" → Spread. "200-node Kafka cluster with fault isolation" → Partition.


AWS CLI — Installation, Config & EC2 Commands

AWS CLI lets you control all AWS services from your terminal. Essential for DevOps — no Console clicking, full automation capability.

Installation:

# Linux/Mac
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version
Enter fullscreen mode Exit fullscreen mode

Configuration:

aws configure
# AWS Access Key ID: [your key]
# AWS Secret Access Key: [your secret]
# Default region name: ap-south-1
# Default output format: json
Enter fullscreen mode Exit fullscreen mode

Credentials stored in ~/.aws/credentials and config in ~/.aws/config.

⚠️ Never hardcode credentials in scripts or push to GitHub. For EC2 accessing AWS services, use IAM Roles with Instance Profiles — no credentials on the instance at all.

Common EC2 CLI commands:

# List all instances (all states)
aws ec2 describe-instances

# List only running instances
aws ec2 describe-instances --filters "Name=instance-state-name,Values=running"

# Launch a new instance
aws ec2 run-instances \
  --image-id ami-0f5ee92e2d63afc18 \
  --instance-type t2.micro \
  --key-name my-key-pair \
  --security-group-ids sg-0123456789abcdef0

# Stop an instance
aws ec2 stop-instances --instance-ids i-1234567890abcdef0

# Start an instance
aws ec2 start-instances --instance-ids i-1234567890abcdef0

# Terminate an instance
aws ec2 terminate-instances --instance-ids i-1234567890abcdef0

# Describe security groups
aws ec2 describe-security-groups

# Create a snapshot
aws ec2 create-snapshot \
  --volume-id vol-0123456789abcdef0 \
  --description "Pre-migration backup"

# Copy snapshot to another region
aws ec2 copy-snapshot \
  --source-region ap-south-1 \
  --source-snapshot-id snap-0123456789abcdef0 \
  --region us-east-1 \
  --description "Cross-region copy"
Enter fullscreen mode Exit fullscreen mode

boto3 — Python SDK for EC2

boto3 is the AWS SDK for Python — write scripts that interact with EC2 (and all AWS services) programmatically.

pip install boto3
Enter fullscreen mode Exit fullscreen mode
import boto3

ec2 = boto3.resource('ec2', region_name='ap-south-1')

# List all EC2 instances and their states
for instance in ec2.instances.all():
    print(f"ID: {instance.id} | Type: {instance.instance_type} | State: {instance.state['Name']}")

# Stop a specific instance
instance = ec2.Instance('i-1234567890abcdef0')
instance.stop()
print("Instance stopped")

# Start a specific instance
instance.start()
print("Instance started")

# Create a snapshot of a volume
ec2_client = boto3.client('ec2', region_name='ap-south-1')
snapshot = ec2_client.create_snapshot(
    VolumeId='vol-0123456789abcdef0',
    Description='Automated daily backup'
)
print(f"Snapshot created: {snapshot['SnapshotId']}")
Enter fullscreen mode Exit fullscreen mode

🎯 DevOps use: Auto-start/stop instances on a schedule (Lambda + EventBridge), automated AMI creation before deployments, custom health check dashboards. This is where your Python-for-DevOps foundation connects directly to AWS infrastructure.


🧪 Lab 1 — Launch EC2 as Web Server with User Data

Objective: Launch an EC2 instance that automatically installs and starts Apache on first boot, serving a custom webpage — without any manual SSH setup.

Steps:

EC2 Console → Launch Instance

Name: lab-webserver
AMI: Amazon Linux 2023 (64-bit x86)
Instance type: t2.micro (Free Tier)
Key pair: create new → lab-key → download .pem
Security Group: Create new lab-sg
Inbound rules: HTTP (80) from 0.0.0.0/0 · SSH (22) from My IP

Advanced details → User Data → paste:

#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd

TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/instance-id)
AZ=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/placement/availability-zone)

cat > /var/www/html/index.html << EOF
<!DOCTYPE html>
<html>
<body style="font-family:Arial;text-align:center;padding:60px;background:#0A1628;color:#fff;">
  <h1 style="color:#FF9900;">Hello from EC2!</h1>
  <p>Instance ID: <b style="color:#FF9900;">$INSTANCE_ID</b></p>
  <p>Availability Zone: <b style="color:#FF9900;">$AZ</b></p>
</body>
</html>
EOF
Enter fullscreen mode Exit fullscreen mode

Launch → wait 2–3 minutes → copy Public IP → open in browser

Expected: a webpage showing your Instance ID and AZ ✅

What to verify:

  • Page loads via HTTP on port 80 ✅
  • Instance ID and AZ are real values from the metadata service ✅
  • SSH works: ssh -i lab-key.pem ec2-user@<public-ip>
  • systemctl status httpd shows Apache is running and enabled ✅

🧪 Lab 2 — EC2 + S3 Access via Instance Profile

Objective: Attach an IAM Role to an EC2 instance so it can access S3 without any credentials configured on the instance.

Steps:

Step 1 — Create S3 bucket
S3 Console → Create bucket → iam-lab-bucket-[yourname] → Create

Step 2 — Upload a test file
Upload a test.txt file with some text content

Step 3 — Create IAM Role for EC2
IAM → Roles → Create Role → AWS Service → EC2
Attach: AmazonS3ReadOnlyAccess
Name: EC2-S3-ReadOnly-Role → Create

Step 4 — Attach role during EC2 launch (or modify existing)
Launch EC2 → Advanced Details → IAM Instance Profile → EC2-S3-ReadOnly-Role
OR on existing: EC2 → Actions → Security → Modify IAM Role → select role → Update

Step 5 — SSH into EC2 and test

# List buckets — no aws configure needed
aws s3 ls
# → your bucket appears ✅

# Download the test file
aws s3 cp s3://iam-lab-bucket-[yourname]/test.txt .
cat test.txt
# → file contents displayed ✅

# Try to write — should fail (ReadOnly policy)
aws s3 cp test.txt s3://iam-lab-bucket-[yourname]/write-test.txt
# → AccessDenied ✅ (Least Privilege working correctly)
Enter fullscreen mode Exit fullscreen mode

What this proves: EC2 accessed S3 using temporary credentials from the Instance Profile and Metadata Service. Zero aws configure, zero hardcoded keys. The AccessDenied on write proves the policy boundary is real.


🧪 Lab 3 — EC2 Resize & EBS Volume Resize

Objective: Change an EC2 instance type and expand an EBS volume without data loss.

Part A — Resize EC2 Instance Type

Step 1: Stop the instance (cannot resize while running)
EC2 → Select instance → Instance State → Stop → wait for Stopped state

Step 2: Change instance type
Actions → Instance Settings → Change Instance Type → select t2.small → Apply

Step 3: Start the instance
Instance State → Start

Step 4: Verify
Instance Type column shows t2.small
SSH in and confirm the instance is fully operational ✅

Part B — Resize EBS Volume (Online — No Downtime)

Step 1: Modify the EBS volume
EC2 → Volumes → select the root volume → Actions → Modify Volume
Change size from 8 GiB to 16 GiB → Modify → confirm
Wait for state to show optimizing then completed

Step 2: Extend the file system inside EC2 (OS doesn't automatically see the new space)
SSH into the running instance:

# Check current disk usage
df -h

# Check the block device (the volume expanded, filesystem hasn't yet)
lsblk

# Grow the partition (for nvme-based instances like t3)
sudo growpart /dev/xvda 1
# or for newer instances:
sudo growpart /dev/nvme0n1 1

# Extend the filesystem
sudo xfs_growfs /     # Amazon Linux 2023 uses XFS
# or for ext4:
sudo resize2fs /dev/xvda1

# Verify new size
df -h
Enter fullscreen mode Exit fullscreen mode

Expected: df -h now shows ~16 GB instead of 8 GB ✅

Key insight: EBS can be expanded without stopping the instance or losing data. But the OS must be told to use the new space — just expanding the volume doesn't automatically extend the file system.


🧪 Lab 4 — Custom AMI Creation & Validation

Objective: Configure an EC2 instance, create a custom AMI from it, and launch a new instance from that AMI to verify it inherits all customizations.

Steps:

Step 1: Configure a base EC2 instance
Launch EC2 (Amazon Linux 2023, t2.micro)
SSH in and customize:

sudo yum update -y
sudo yum install -y nginx git
sudo systemctl start nginx
sudo systemctl enable nginx

# Create a custom welcome page
echo "<h1>Custom AMI - $(date)</h1>" | sudo tee /usr/share/nginx/html/index.html

# Verify Nginx is serving
curl localhost
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the AMI
EC2 Console → Instances → select your instance
Actions → Image and Templates → Create Image

Image name: custom-nginx-ami
Image description: Amazon Linux 2023 with Nginx pre-installed
No reboot: leave unchecked (AWS will reboot to ensure a consistent snapshot)
Create Image → note the AMI ID

Wait 5–10 minutes for status to change from pending to available

Step 3: Launch a new instance from your AMI
EC2 → Launch Instance
AMI → My AMIs → select custom-nginx-ami
t2.micro, same security group (HTTP 80 + SSH 22) → Launch

Step 4: Validate
Wait 2 minutes → open the new instance's Public IP in browser
Expected: Nginx serves your custom page — without any User Data script ✅

Step 5: SSH and verify

ssh -i lab-key.pem ec2-user@<new-instance-ip>
nginx -v              # Nginx is installed ✅
systemctl status nginx # Nginx is running ✅
cat /usr/share/nginx/html/index.html  # Custom page is there ✅
Enter fullscreen mode Exit fullscreen mode

What this demonstrates: The AMI captured the entire state of the configured instance. Any new instance launched from this AMI starts with Nginx pre-installed, pre-configured, and serving — no setup required.


🧪 Lab 5 — EBS Snapshot Cross-Region Copy

Objective: Create an EBS snapshot, copy it to another Region, and restore it as a new volume there. This is the foundation of cross-region disaster recovery and data migration.

Steps:

Step 1: Create a snapshot of your EBS volume
EC2 → Volumes → select your volume → Actions → Create Snapshot
Description: cross-region-dr-snapshot → Create Snapshot
Note the Snapshot ID (snap-xxxxxxxx)
Wait for State to show completed

Step 2: Copy snapshot to another Region

Via Console:

EC2 → Snapshots → select your snapshot → Actions → Copy Snapshot
Destination Region: us-east-1 (N. Virginia)
Description: Copied from ap-south-1 for DR testing → Copy Snapshot

Via CLI:

aws ec2 copy-snapshot \
  --source-region ap-south-1 \
  --source-snapshot-id snap-0123456789abcdef0 \
  --region us-east-1 \
  --description "DR copy from Mumbai to Virginia"
Enter fullscreen mode Exit fullscreen mode

Step 3: Switch Region in Console to us-east-1
Verify the copied snapshot appears in Snapshots → completed status ✅

Step 4: Create a volume from the copied snapshot
Select the snapshot → Actions → Create Volume from Snapshot
Volume type: gp3, Size: same as source
AZ: us-east-1a (or any AZ in us-east-1)
Create Volume

Step 5: Attach to an EC2 in us-east-1 and verify data
Launch a t2.micro EC2 in us-east-1
EC2 → Volumes → select the new volume → Actions → Attach Volume → select instance
SSH into the EC2:

# List block devices
lsblk
# New volume appears (e.g., /dev/xvdf)

# Mount it
sudo mkdir /data
sudo mount /dev/xvdf /data

# Verify the data from Mumbai is accessible
ls /data
cat /data/[any-file-from-source-instance]
# → Data from Mumbai visible in Virginia ✅
Enter fullscreen mode Exit fullscreen mode

Real-world use cases for cross-region snapshot copy:

  • Disaster Recovery: Primary Region fails → restore from snapshot in DR Region → minimal data loss
  • Data Migration: Moving workloads from one Region to another
  • Global Compliance Testing: Test with production data copy in a different Region without touching production
  • Multi-Region Backup: Regulatory requirement to keep backups in multiple geographies

⚡ Quick Revision

EC2 Instance Families

  • t/m = General Purpose · c = Compute · r = Memory · i/d = Storage · p/g = GPU

ENI

  • Virtual network card — carries private IP, public IP, Elastic IP, MAC, Security Groups
  • Applied at ENI level, not instance level — one instance can have multiple ENIs

EBS Volume Types

  • gp3 = default, most workloads (set IOPS/throughput independently)
  • io2 = high-performance databases, Multi-Attach
  • st1 = big data throughput, sequential reads
  • sc1 = cold/infrequent access, cheapest

AMI

  • Blueprint for EC2: OS + software + config + root volume snapshot
  • Region-specific — must copy AMI to use in another Region
  • EBS-backed = can stop/start, use always · Instance Store-backed = legacy, avoid
  • Sharing: private (default) / shared with account IDs / public

Lifecycle

  • Running → billed per second
  • Stopped → EBS billed, compute not billed, can restart
  • Hibernated → RAM saved to EBS, resumes exactly where left off
  • Terminated → gone forever, not recoverable

Status Checks

  • System check fails → Stop + Start (moves to new physical host)
  • Instance check fails → Reboot (fixes OS, stays on same host)

Placement Groups

  • Cluster = low latency, same AZ, HPC workloads
  • Spread = max isolation, separate racks, max 7 per AZ
  • Partition = distributed systems, many nodes per partition

Pricing

  • On-Demand = pay per second, no commitment
  • Reserved = 1–3 years, 30–70% savings
  • Spot = up to 90% off, can be interrupted with 2-min notice

Elastic IP

  • Free when attached to a running instance
  • Charged when idle or attached to a stopped instance — always release after labs

💼 Interview Questions

Q1: What is the difference between stopping and terminating an EC2 instance?
Stopping shuts the instance down — EBS data persists, compute billing stops, you can start it again. Terminating permanently deletes the instance and by default its root EBS volume. There is no recovery from termination.

Q2: An EC2 instance is in a different AZ than your EBS volume. Can you attach it?
No. EBS volumes are AZ-locked. To use EBS data across AZs: take a snapshot of the volume → create a new volume from that snapshot in the target AZ → attach to EC2 in that AZ.

Q3: What is the difference between Instance Store and EBS?
Instance Store is physical storage attached to the EC2 host — very fast but completely lost when the instance stops, terminates, or the underlying host fails. EBS is persistent network-attached storage that survives stop/restart and can be detached and reattached to other instances.

Q4: A system status check is failing on your EC2. What do you do?
Stop and Start the instance — not Reboot. This moves the instance to a new physical host. Rebooting keeps it on the same failing hardware and won't resolve a system-level infrastructure issue.

Q5: What is EC2 Hibernate and when would you use it?
Hibernate saves the entire RAM contents to the encrypted EBS root volume, then stops the instance. When started again, the OS and all applications resume exactly where they left off — no boot time, no re-initialization. Use it for long-running workloads that are expensive to restart — ML training checkpoints, complex stateful processes, developer environments you want to resume quickly.

Q6: What is the difference between EBS-backed and Instance Store-backed AMIs?
EBS-backed AMIs have the root volume stored as an EBS snapshot — instances can be stopped and restarted, and data on the root volume persists. Instance Store-backed AMIs store the root volume in S3 — instances cannot be stopped (only terminated), and root volume data is lost on termination. Always use EBS-backed AMIs.

Q7: When would you use a Cluster vs Spread placement group?
Cluster for workloads needing ultra-low latency and high throughput between instances — HPC, ML training. Spread for critical instances that must be isolated from each other's hardware failures — each instance goes on a separate physical rack, maximum 7 per AZ.

Q8: What are the real-world use cases for copying an EBS snapshot to another Region?
Cross-region disaster recovery (restore in DR Region if primary fails), data migration between Regions, regulatory compliance requiring backups in multiple geographies, and testing with production data in a non-production Region.


🔬 Practice Tasks

  1. Launch an EC2 with a User Data script that installs Nginx (not Apache) and serves a custom page showing the instance ID, type, and region — all fetched from the metadata service. Access via public IP.

  2. Allocate an Elastic IP. Launch an EC2. Note its public IP. Stop the instance — confirm the dynamic IP changed. Attach the Elastic IP. Stop and start again — confirm the IP stays the same. Release the Elastic IP when done.

  3. Attach a second EBS volume to a running EC2 instance. SSH in, format it (mkfs.xfs), mount it, write a file to it. Stop the instance. Start it again. Confirm the file persists (note: you'll need to remount — add to /etc/fstab for automatic mount).

  4. Expand an EBS volume from 8 GB to 20 GB on a running instance (no downtime). SSH in and extend the file system using growpart and xfs_growfs. Verify with df -h.

  5. Create a custom AMI from a configured EC2 instance. Launch a second instance from that AMI. Verify all customizations are present without any manual setup.

  6. Create a snapshot, copy it to a different Region via CLI, create a volume from it, attach to an EC2 in that Region, mount it, and verify the data from the original Region is accessible.

  7. Using AWS CLI: describe all running instances, stop one by instance ID, start it again, create a snapshot of its root volume — all without touching the Console.

  8. Use calculator.aws to estimate the monthly cost of: 1 × t3.micro EC2 (Linux, ap-south-1, 24/7) + 20 GB gp3 EBS + 100 GB data transfer out. Then estimate the same setup on Reserved Instance pricing (1 year, no upfront). Note the difference in monthly cost.

  9. Using boto3: write a Python script that lists all EC2 instances in ap-south-1, prints their ID, type, and state, and automatically stops any instance in running state that has a tag Environment: dev.


AWS Session 4 — EC2 Essentials | Cloud + DevOps learning journey — Systems Engineer → Cloud/DevOps Engineer

Top comments (0)